I have this code
int f(int i){
return i;
}
int main(){
cout << std::boolalpha;
using f_1 = decltype(f);
using f_2 = decltype((f));
cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
cout << is_same<std::result_of_t<f_2(int)>, int>::value<< endl; // OK
return 0;
}
If I am correct, decltype(f) will return the type of the function which will be int(int). decltype((f)) will return the type of reference of the function which will be int(&)(int).
In the documentation of result_of, it said: F must be a callable type, reference to function, or reference to callable type. Invoking F with ArgTypes... must be a well-formed expression.
So is that mean a function type is not an callable type?
Error info is
1.23.cpp: In function ‘int main()’:
1.23.cpp:35:38: error: ‘type name’ declared as function returning a function
35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
| ^~~
1.23.cpp:35:46: error: template argument 1 is invalid
35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
| ^
1.23.cpp:35:52: error: template argument 1 is invalid
35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
| ^
A function cannot have a function type as return type. It can have a reference-to-function return type though.
So already in terms of the simple meaning of the syntax
f1(int), the program is ill-formed. It would denote the type of a function that takes anintand returns a function type (f1).The behavior of
std::result_ofusing an invented function type as template argument is a bit weird and causes these issues. That's one of the reasons it has been replaced withstd::invoke_resultwhich takes the callable and argument types as individual template arguments, so that no function type needs to be invented.