yohhoyの日記

技術的メモをしていきたい日記

関数名/メンバ関数名とアドレス演算子

プログラミング言語C++において、通常関数名やstaticメンバ関数名から関数ポインタ型へは暗黙変換が行われるが、メンバ関数名からメンバ関数ポインタ型への変換はアドレス演算子&利用が必須。

void f0();
struct S {
  static void f1();
  void mf();
};

// (通常)関数/staticメンバ関数
using PF = void (*)();
PF p0a = &f0;  // OK
PF p0b =  f0;  // OK: 暗黙変換
PF p1a = &S::f1;  // OK
PF p1b =  S::f1;  // OK: 暗黙変換

// メンバ関数
using PMF = void (S::*)();
PMF pmfa = &S::mf;  // OK
PMF pmfb =  S::mf;  // NG: ill-formed

C++03 4.3/p1, 5.1/p10より一部引用。C++20現在は7.3.4/p1, 7.5.4.1/p2が対応。

An lvalue of function type T can be converted to an rvalue of type "pointer to T." The result is a pointer to the function.50)

脚注50) This conversion never applies to nonstatic member functions because an lvalue that refers to a nonstatic member function cannot be obtained.

An id-expression that denotes a nonstatic data member or nonstatic member function of a class can only be used:

  • (snip)
  • to form a pointer to member (5.3.1), or
  • (snip)

関連URL