As I know, a possible implementation of std::result_of
is
template<class F, class... ArgTypes>
struct result_of<F(ArgTypes...)>
{
typedef decltype(
std::declval<F>()(std::declval<ArgTypes>()...)
) type;
};
But when I use std::result_of
I have some trouble.
int f(int x)
{
return 0;
}
template<typename T>
void Test(const T& t)
{
decltype(std::declval<T>()(std::declval<int>())) i1 = 1; // ok
typename std::result_of<T(int)>::type i2 = 2; // compile error:
// function returning a function
// I think this means the same thing just as above, right?
}
int main()
{
Test(f);
return 0;
}
What are the differences between these two forms?
std::result_of
is declared in C++11 [meta.trans.other] Table 57 as:
template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
and it requires that:
Fn
shall be a callable type (20.8.1), reference to function, or reference to callable type. The expressiondecltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...))
shall be well formed.
callable type is defined in [func.def]/3:
A callable type is a function object type (20.8) or a pointer to member.
function object type is defined in [function.objects]/1:
A function object type is an object type (3.9) that can be the type of the postfix-expression in a function call (5.2.2, 13.3.1.1). ...
In your program, f
is a reference to a function of type int(int)
, so T
is deduced to the function type int(int)
. Note that a function type is not one of the valid options for the type Fn
to be passed to std::result_type
. A reference to function is an acceptable type, however: you should pass the full type of Test
s parameter to result_of
instead of only T
( Demo at Coliru ):
template<typename T>
void Test(const T&)
{
decltype(std::declval<T>()(std::declval<int>())) i1 = 1;
typename std::result_of<const T& (int)>::type i2 = 2;
}
Regarding the difference between the two forms, remember that std::declval
always returns a reference type; specifically std::declval<T>()
returns T&&
. So
decltype(std::declval<T>()(std::declval<int>()))
is asking for the what type is returned when a T&&
is invoked with an int&&
argument.
[basic.compound] describes what function types look like in C++:
— functions , which have parameters of given types and return
void
or references or objects of a given type
Therefore, the return type part of a function type must not itself be a function type, and thus T(int)
is not a valid type in the C++ type system when T = int(int)
.
Moreover, [dcl.fct]/8 clarifies:
Functions shall not have a return type of type array or function
Note also that the actual analogue of your i1
line is typename std::result_of<T>::type i2
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.