关于c ++ 11中的std :: result_of

Leo*_*all 2 c++ c++11

据我所知,可能的实现std::result_of

template<class F, class... ArgTypes>
struct result_of<F(ArgTypes...)>
{
    typedef decltype(
        std::declval<F>()(std::declval<ArgTypes>()...)
        ) type;
};
Run Code Online (Sandbox Code Playgroud)

但是当我使用时我std::result_of遇到了一些麻烦.

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

这两种形式有什么区别?

Cas*_*sey 5

std::result_of 在C++ 11中声明[meta.trans.other]表57如下:

template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
Run Code Online (Sandbox Code Playgroud)

它要求:

Fn应该是可调用类型(20.8.1),对函数的引用或对可调用类型的引用.表达方式

decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...))
Run Code Online (Sandbox Code Playgroud)

应该很好.

可调用类型在[func.def]/3中定义:

可调用类型是一个功能对象类型(20.8)或指针构件.

函数对象类型在[function.objects]/1中定义:

功能对象类型是对象类型(3.9),其可为类型后缀表达式在一个函数调用(5.2.2,13.3.1.1)....

在你的程序中,f是对类型函数的引用int(int),因此T推导出函数类型int(int).请注意,函数类型不是Fn要传递给的类型的有效选项之一std::result_type.对函数的引用可接受的类型,但是:您应该传递完整类型的Tests参数result_of而不是仅传递T(在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;
}
Run Code Online (Sandbox Code Playgroud)

关于两种形式之间的区别,请记住std::declval始终返回引用类型; 特别std::declval<T>()回报T&&.所以

decltype(std::declval<T>()(std::declval<int>()))
Run Code Online (Sandbox Code Playgroud)

是在询问T&&使用int&&参数调用a时返回的类型.