为什么不是std :: result_of <int(int)> :: type有效?

时间:2015-06-18 15:16:19

标签: c++ c++11

我已阅读以下相关问题:

  1. std::result_of simple function
  2. decltype, result_of, or typeof?
  3. the page on std::result_of at cppreference.com

    所有这些似乎表明我应该可以使用:

     std::result_of<int(int)>::type v1 = 10;
    

    但是,当我尝试使用g ++ 4.9.2

    构建以下程序时
    #include <type_traits>
    
    int foo()
    {
       return 0;
    }
    
    int main()
    {
        std::result_of<int(int)>::type v1 = 10;           // LINE A
        std::result_of<decltype(foo)>::type v2 = 20;      // LINE B
        return 0;
    }
    

    我收到&#34; LINE A&#34;的错误消息和&#34; LINE B&#34;。错误消息是:

    socc.cc: In function ‘int main()’:
    socc.cc:10:5: error: ‘type’ is not a member of ‘std::result_of<int(int)>’
         std::result_of<int(int)>::type v1 = 10;
         ^
    socc.cc:11:5: error: ‘type’ is not a member of ‘std::result_of<int()>’
         std::result_of<decltype(foo)>::type v2 = 20;
         ^
    

    我用来编译的命令:

    g++ -std=c++11 -Wall    socc.cc   -o socc
    

    FWIW,使用

     typename std::result_of<int(int)>::type v1 = 10;
     typename std::result_of<decltype(foo)>::type v2 = 20;
    

    没有什么区别。

    似乎我无法理解应该如何使用result_of

    你能解释我为什么会收到编译错误吗?

3 个答案:

答案 0 :(得分:12)

您似乎假设std::result_of<R(Args...)>::type只是R - 也就是具有签名R(Args...)的函数的结果类型。但是std::result_of<F(Args...)>::type是使用F类型的参数调用类型为Args...的实例的结果。

因此,std::result_of<int(int)>::type没有意义 - int对象不可调用。

请再次阅读cppreference:)

答案 1 :(得分:11)

如您已发布的链接中所述,result_of的参数的第一部分必须是可调用类型或对函数的引用。

假设你有一个

struct Callable
{
    int operator()(double);
    void operator()(int);
};

然后result_of可以帮助您确定返回类型,如果您知道参数的类型。对于上面的例子:

result_of<Callable(int)>::type == void    ... per definition
result_of<Callable(double)>::type == int  ... per definition
result_of<Callable(char)>::type == void   ... the int-overload matches better
result_of<Callable(float)>::type == int   ... the double-overload matches better

为了找到函数foo的返回类型,你必须通过函数引用:

result_of<decltype(foo)& ()>::type == int

但这似乎有点扭曲,因为你可以直接写

decltype(foo()) == int

答案 2 :(得分:3)

要使用result_of,提供的类型必须是函数类型,其中返回类型是Callable的类型,参数列表包含要调用它的参数类型。 result_of<int(int)>因此询问&#34;当我使用参数declval<int>()&#34;来调用declval<int>()时,我会得到什么类型。答案是没有类型,因为int不是函数类型。

以下是表57的摘录:

  

如果表达式INVOKE(declval<Fn>(), declval<ArgTypes>()...)在被视为未评估的操作数(第5条)时格式良好,则成员typedef类型应将类型命名为decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...));,否则将不存在成员type

给定函数foo,您可以使用:

 std::result_of_t<decltype((foo))()> v1 = 10;
 std::result_of_t<decltype(&foo)()> v2 = 10;