Address of an overloaded function
함수 호출 표현식 이 일어나는 경우를 제외하고, 오버로드된 함수의 이름은 다음 7가지 컨텍스트에서 나타날 수 있습니다:
| # | Context | Target |
|---|---|---|
| 1 | initializer in a declaration of an object or reference | 초기화되는 객체 또는 참조 |
| 2 | 내장 할당 표현식의 우변 | 내장 할당의 좌변 |
| 3 | 함수 호출 인자 | 함수 매개변수 |
| 4 | 사용자 정의 연산자 인자 | 연산자 매개변수 |
| 5 |
the
return
statement
|
함수 또는 변환의 반환값 |
| 6 |
explicit cast
or
static_cast
argument
|
해당 캐스트 |
| 7 | constant template argument | 해당 템플릿 매개변수 |
각 컨텍스트에서, 오버로드된 함수의 이름 앞에는 주소 연산자
&
가 올 수 있으며, 중복된 괄호 세트로 둘러싸일 수 있습니다.
|
대상 타입이 플레이스홀더 타입 을 포함하는 경우, 플레이스홀더 타입 추론이 수행되며, 다음 설명에서는 추론된 타입을 대상 타입으로 사용합니다. |
(since C++26) |
목차 |
함수 선택
오버로드된 함수의 주소를 취할 때, 오버로드 함수의 이름으로 참조되는 오버로드 집합에서 함수들의 집합
S
가 선택됩니다:
- 대상이 없는 경우, 명명된 모든 비템플릿 함수가 선택됩니다.
-
그렇지 않으면, 대상 타입의 함수 타입
FT에 대해 타입F를 가진 비템플릿 함수가F( 함수 포인터 변환 을 가능하게 적용한 후) (C++17부터) 가FT와 동일할 경우 선택됩니다. [1] -
각 함수 템플릿에 대해
템플릿 인수 추론
으로 생성된 특수화(존재하는 경우)도
S에 추가됩니다.
대상이 함수 포인터 타입이거나 함수 타입에 대한 참조인 경우,
S
는 비멤버 함수만 포함할 수 있습니다
, 명시적 객체 멤버 함수
(C++23부터)
및 정적 멤버 함수. 대상이 멤버 함수 포인터 타입인 경우,
S
는 암시적 객체 멤버 함수만 포함할 수 있습니다.
- ↑ 달리 말하면, 대상 타입이 멤버 함수 포인터 타입인 경우 함수가 멤버인 클래스는 무시됩니다.
함수 제거
집합
S
를 형성한 후, 함수들은 다음 순서로 제거됩니다:
|
(since C++20) |
-
S에 둘 이상의 함수가 남아 있는 경우,S에 비템플릿 함수가 포함되어 있으면S내의 모든 함수 템플릿 특수화가 제거됩니다.
|
(C++20부터) |
-
주어진 함수 템플릿 특수화
spec
는
S에 함수 템플릿이 spec 의 함수 템플릿보다 더 특수화된 두 번째 함수 템플릿 특수화를 포함하는 경우 제거됩니다.
이러한 제거 후(있는 경우) 정확히 하나의 선택된 함수가
S
에 남아 있어야 합니다. 그렇지 않으면 프로그램이 형식에 맞지 않습니다.
예제
int f(int) { return 1; } int f(double) { return 2; } void g(int(&f1)(int), int(*f2)(double)) { f1(0); f2(0.0); } template<int(*F)(int)> struct Templ {}; struct Foo { int mf(int) { return 3; } int mf(double) { return 4; } }; struct Emp { void operator<<(int (*)(double)) {} }; int main() { // 1. 초기화 int (*pf)(double) = f; // int f(double) 선택 int (&rf)(int) = f; // int f(int) 선택 int (Foo::*mpf)(int) = &Foo::mf; // int mf(int) 선택 // 2. 대입 pf = nullptr; pf = &f; // int f(double) 선택 // 3. 함수 인자 g(f, f); // 첫 번째 인자로 int f(int) 선택 // 두 번째 인자로 int f(double) 선택 // 4. 사용자 정의 연산자 Emp{} << f; // int f(double) 선택 // 5. 반환 값 auto foo = []() -> int (*)(int) { return f; // int f(int) 선택 }; // 6. 캐스트 auto p = static_cast<int(*)(int)>(f); // int f(int) 선택 // 7. 템플릿 인자 Templ<f> t; // int f(int) 선택 // [[maybe_unused]]처럼 "사용되지 않은 변수" 경고 방지 [](...){}(pf, rf, mpf, foo, p, t); }
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 202 | C++98 |
상수 템플릿 인수가 오버로드된 함수의 주소를 취하는
문맥이 아니었음 |
해당 문맥임 |
| CWG 250 | C++98 |
추론되지 않은 템플릿 인수로 생성된 함수 템플릿 특수화가
오버로드 집합에서 선택되지 않았음 |
또한 선택됨 |
| CWG 1153 | C++98 | 주어진 함수 타입이 대상 타입과 일치하는지 불명확했음 | 명확히 함 |
| CWG 1563 | C++11 |
목록 초기화가 오버로드된 함수의 주소를 취하는 문맥인지
불명확했음 |
명확히 함 |
참고문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 12.3 오버로드된 함수의 주소 [over.over]
- C++20 표준 (ISO/IEC 14882:2020):
-
- 12.5 오버로드된 함수의 주소 [over.over]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 16.4 오버로드된 함수의 주소 [over.over]
- C++14 표준(ISO/IEC 14882:2014):
-
- 13.4 오버로드된 함수의 주소 [over.over]
- C++11 표준 (ISO/IEC 14882:2011):
-
- 13.4 오버로드된 함수의 주소 [over.over]
- C++98 표준 (ISO/IEC 14882:1998):
-
- 13.4 오버로드된 함수의 주소 [over.over]