문제의 역사
C++는 초기에 함수 오버로딩을 지원하는 언어로 설계되었습니다. 이는 동일한 이름의 여러 함수를 다양한 매개변수로 선언할 수 있는 기능을 제공합니다. 이는 읽기 쉽고 편리한 API를 만드는 데 도움이 됩니다.
문제
동일한 이름을 가진 함수가 많아지면, 컴파일러는 모든 오버로드 된 함수에서 적절한 구현을 선택해야 합니다. 이때 인수의 유형, 변환, 기본 매개변수 및 참조를 고려해야 합니다. 부주의한 오버로딩을 사용할 경우 모호성과 찾기 힘든 오류가 발생합니다.
해결 방법
컴파일러는 인수의 최적 일치, 유형 일치의 정확성 및 최소한의 변환을 기반으로 함수를 선택합니다. 하지만 중요한 변환이나 기본 인수가 있는 경우 예상치 못한 모호성이 발생할 수 있습니다.
코드 예시:
void foo(int x); void foo(double x); void foo(int x, int y = 0); foo(5); // void foo(int x)를 호출합니다. 정확하게 일치함 foo(5.2); // void foo(double x)를 호출합니다 foo(5, 6); // void foo(int x, int y)를 호출합니다
주요 특징:
반환 타입만으로 함수를 오버로딩할 수 있나요?
아니요. 오버로딩은 오직 매개변수의 유형과 수에 의해서만 가능하며, 반환 타입은 오버로드 해상도에 참여하지 않습니다.
int foo(); double foo(); // 오류: 반환 타입만으로 오버로딩할 수 없습니다!
모든 매개변수가 변환 가능할 경우, 컴파일러는 어떤 오버로드된 함수를 선택하나요?
컴파일러는 "최적 일치" 즉, 필요한 최소한의 유형 변환이거나 정확한 일치를 요구하는 함수를 선택합니다. 모호성이 존재할 경우, 코드는 컴파일되지 않습니다.
void bar(int); void bar(long); bar(1); // int가 정확한 일치: bar(int)을 호출합니다
기본 인수와 일반 오버로딩을 혼합할 수 있나요?
가능하지만 함수의 시그니처가 겹치는 경우 호출의 모호성을 초래할 수 있습니다.
void test(int x); void test(int x, int y = 10); test(5); // 오류: 모호성 — 두 함수 모두 적합합니다
라이브러리에서 기본 인수가 겹치는 오버로드된 함수들이 발견되어, 코드 업데이트 시 컴파일 오류가 발생합니다.
장점:
단점:
프로젝트에서 기본 인수를 가진 오버로딩을 혼합하지 않거나, 기본 값을 가진 함수 또는 고유한 매개변수로만 오버로딩하는 규칙을 도입했습니다.
장점:
단점: