overloaded_address — 오버로드된 함수의 주소
overloaded_address — 오버로드된 함수의 주소 (Address of an overloaded function)
오버로드된 함수의 주소는 오버로드 해석이 일어나는 함수 호출 표현식 외에도, 오버로드된 함수의 이름이 다음 7가지 문맥에서 나타날 수 있어요.
컴파일러는 문맥에 따라 어느 오버로드의 주소를 취할지 결정해요.
출처: cppreference
본문
오버로드된 함수 이름이 나타날 수 있는 문맥과 대상은 다음과 같아요.
| 문맥 | 대상 |
|---|---|
| 객체나 참조 선언의 초기화자 | 초기화되는 객체나 참조 |
| 대입 표현식의 오른쪽 | 대입의 왼쪽 |
| 함수 호출 인자 | 함수 매개변수 |
| 사용자 정의 연산자 인자 | 연산자 매개변수 |
return 문 |
함수나 변환의 반환 값 |
명시적 캐스트(cast) 또는 static_cast 인자 |
해당 캐스트 |
| 비타입 템플릿 매개변수 | 해당 템플릿 매개변수 |
int f(int);
double f(double);
int (*p1)(int) = f; // f(int) 선택 — 대상 타입이 int(*)(int)
double (*p2)(double) = f; // f(double) 선택
오버로드된 함수의 이름은 대상 타입이 주어질 때 그 타입에 맞는 오버로드가 선택돼요. 대상 타입이 매치되는 오버로드가 정확히 하나면 그 주소가 취해지고, 없거나 여러 개면 오류가 나요.
// 함수 포인터로 선택
auto fp = static_cast<int(*)(int)>(f); // f(int) 명시적 선택
// 함수 참조로 선택
int (&r)(int) = f; // f(int)
// 함수 템플릿 인자로
template<int(*F)(int)> struct Wrapper {};
Wrapper<f> w; // f(int)
오버로드된 함수의 주소를 취할 때는 "문맥이 기대하는 함수 타입(시그니처)"이 어느 것을 고를지 결정해요. 시그니처가 정확히 하나의 오버로드와만 맞아야 해요.
// 모호한 경우 — 대상 타입이 없으면 오류
// void take(int(*)(int));
// take(&f); // f(int) 선택되면 OK
이 기능은 콜백이나 함수 포인터를 인자로 받는 API에 특정 오버로드를 전달할 때, 그리고 함수 템플릿·표준 알고리즘에 함수 포인터를 넘길 때 유용해요.