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 an int
and returns a function type (f1
).
The behavior of std::result_of
using 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 with std::invoke_result
which takes the callable and argument types as individual template arguments, so that no function type needs to be invented.