为什么'X x; X();' 允许,当'X'定义转换为函数指针时,但不是,当它定义转换为仿函数时?

Xeo*_*Xeo 29 c++ function-pointers functor function-call

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 ?!
}
Run Code Online (Sandbox Code Playgroud)

Ideone上的实例.输出:

错误:调用'(Y)(int)'不匹配

Q1:为什么调用x(5)允许,即使X只定义了转换为函数指针,而不是operator()

Q2:相反,如果我们定义转换为另一个仿函数,为什么不允许相同的事情?

小智 26

x(5); // works ?!
Run Code Online (Sandbox Code Playgroud)

这隐含地转换xf_ptr并调用它.C++ 11标准:

§13.3.1.1.2调用类类型的对象[over.call.object]

2)另外,对于在表格的T中声明的每个非显式转换函数

operator conversion-type-id ( ) attribute-specifier-seqopt cv-qualifier ;
Run Code Online (Sandbox Code Playgroud)

[... where conversion-type-id表示类型" (P1,...,Pn)返回功能的指针R"...]


y(5); // doesn't ?!
Run Code Online (Sandbox Code Playgroud)

该标准没有提及任何关于重载operator()(类型函子)的类类型的隐式转换,这意味着编译器不允许这样做.

你必须明确地强制转换它:

static_cast<Functor>(y)(5);
Run Code Online (Sandbox Code Playgroud)