반응형

C++ 함수 오버로딩(overloading) '더 나은 변환(better conversion)'

  • C++에서 함수 오버로딩 시 "더 나은 변환(better conversion)" 이라는 개념은 함수 호출 시 여러 후보 함수 중에서 어떤 함수를 선택할지를 결정하는 중요한 원칙입니다.
  • 이 원칙은 각 후보 함수의 인자 변환 비용을 비교 해, 더 자연스럽고 가까운 타입으로 변환 가능한 함수를 선택하는 방식입니다.


'더 나은 변환(better conversion)' 이란 무엇인가?

  • 함수를 호출할 때 여러 후보 함수가 존재하면, 컴파일러는 다음과 같은 변환 순위를 따져서 '더 나은 변환'을 선택합니다:

변환 우선순위 (간단 정리)

  • (1) 정확히 같은 타입(Exact Match)
  • (2) 승격 변환(Promotion)
    • 예: charint, floatdouble
  • (3) 표준 변환(Standard Conversion)
    • 예: 포인터 간 변환, nullptr_t → 포인터
  • (4) 사용자 정의 변환(User-defined Conversion)
  • (5) 가변 인자 변환(Ellipsis 변환, ...)

  • 순위가 높을수록 변환이 '더 나은 변환'으로 간주됩니다.


nullptr의 함수 오버로딩 처리 규칙

  • std::nullptr_t 타입은 모든 포인터 타입으로 변환 가능한 특별한 타입입니다.

  • 그렇다면 하단의 func(nullptr) 호출 시 char* 버전과 void* 버전이 모두 가능할 경우 어느 쪽이 선택될까요?

  • cpp

      #include <iostream>
      
      using namespace std;
      
      void func(char* str)   { cout << "char* version" << endl; }
      void func(int i)       { cout << "int version" << endl; }
      void func(void* str)   { cout << "void* version" << endl; }
      
      int main()
      {
      	func(NULL);
      	func(nullptr);
      
      	return 0;
      }
    
  • 👉 규칙 정리

    • nullptr → 포인터 변환은 모두 표준 변환에 해당합니다.
    • nullptrvoid* 변환은 더 자연스럽고 일반적인 변환 으로 간주됩니다.
    • C++ 표준과 여러 컴파일러(GCC, Clang, MSVC)의 동작에 따르면:
      • nullptr 인자가 여러 포인터 오버로딩 후보에서 충돌할 경우 void* 버전이 우선 선택됩니다.

정리

  • 호출 선택되는 함수 버전
    func(NULL) int version 호출 (정수 리터럴 0으로 처리)
    func(nullptr) void* version 호출 (표준 변환 우선순위에 의해)


관련 표준 근거 (C++ 표준 §12.2.4.2.1 일부)

  • "A conversion from std::nullptr_t to a pointer type is a standard conversion."
  • "When multiple standard conversions are possible, the conversion requiring the least complex transformation (least rank) is chosen."
  • "If ambiguity exists between a non-void pointer and a void pointer conversion from std::nullptr_t, the void* conversion is considered at least as good or better."




  • 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄

728x90
반응형

+ Recent posts