Why is 'X x; x();' allowed, when 'X' defines a conversion to function pointer, but not, when it defines a conversion to a functor?
-
28-10-2019 - |
Question
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 ?!
}
Live example on Ideone. Output:
error: no match for call to '(Y) (int)'
Q1: Why is the call to x(5)
allowed, even though X
only defines a conversion to function pointer, and not operator()
?
Q2: Conversely, why is the same thing not allowed, if we define a conversion to another functor?
Solution
x(5); // works ?!
This implicitly casts x
to an f_ptr
and calls that. C++11 standard:
§ 13.3.1.1.2 Call to object of class type [over.call.object]
2) In addition, for each non-explicit conversion function declared in T of the form
operator conversion-type-id ( ) attribute-specifier-seqopt cv-qualifier ;
[…where
conversion-type-id
denotes the type “pointer to function of(P1,...,Pn)
returningR
”…]
y(5); // doesn't ?!
The standard doesn't mention anything about implicit conversion to class types that overload operator()
(aka functors), which implies that the compiler doesn't allow that.
You must cast it explicitly:
static_cast<Functor>(y)(5);