29
void f(int){}
typedef void (*f_ptr)(int);

struct Functor{
  void operator()(int){}
};

struct X{
  operator f_ptr(){ return f; }
};

struct Y{
  operator Functor(){ return Functor(); }
};

int main(){
  X x; Y y;
  x(5); // works ?!
  y(5); // doesn't ?!
}

Ideoneの実例。出力:

エラー:「(Y)(int)」の呼び出しに一致しません

Q1:関数ポインタへの変換のみを定義し、定義しx(5)ていないのに、なぜ呼び出しが許可されるのですか?Xoperator()

Q2:逆に、別のファンクターへの変換を定義した場合、同じことが許可されないのはなぜですか?

4

1 に答える 1

25
x(5); // works ?!

これは暗黙的ににキャストxし、f_ptrそれを呼び出します。C ++ 11標準:

§13.3.1.1.2クラスタイプ[over.call.object]のオブジェクトへの呼び出し

2)さらに、次の形式のTで宣言された非明示的な変換関数ごとに

operator conversion-type-id ( ) attribute-specifier-seqopt cv-qualifier ;

[…ここで、は「戻るconversion-type-id関数へのポインタ」のタイプを示します…](P1,...,Pn)R


y(5); // doesn't ?!

operator()この標準では、オーバーロードするクラス型(別名ファンクター)への暗黙的な変換については何も言及されていません。これは、コンパイラーがそれを許可しないことを意味します。

明示的にキャストする必要があります。

static_cast<Functor>(y)(5);
于 2012-01-15T20:45:25.333 に答える