Namespaces
Variants

Address of an overloaded function

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

함수 호출 표현식 이 일어나는 경우를 제외하고, 오버로드된 함수의 이름은 다음 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 는 암시적 객체 멤버 함수만 포함할 수 있습니다.

  1. 달리 말하면, 대상 타입이 멤버 함수 포인터 타입인 경우 함수가 멤버인 클래스는 무시됩니다.

함수 제거

집합 S 를 형성한 후, 함수들은 다음 순서로 제거됩니다:

  • 연관된 constraints 가 만족되지 않는 모든 함수들은 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]