为什么std :: result_of不适用于lambdas?

时间:2015-02-19 23:09:48

标签: c++ c++11 gcc lambda

我设法将我的案例简化为以下最简单的代码:

#include <type_traits>

auto call(const auto& f) -> typename std::result_of<decltype(f)()>::type
{
  return f();
}

int main()
{
  return call([] { return 0; });
}

gcc-4.9.2和gcc-5.0.0都没编译!

两人都认为&#34;打电话&#34;应该返回一个lambda函数! 不要弄清楚&#34;打电话&#34;返回一个int。

这是编译器中的错误还是我的c ++关闭? 非常感谢。

3 个答案:

答案 0 :(得分:13)

您的代码无效C ++,因为函数参数类型不能是auto,这种语法已经为Concepts Lite提出,并且可能在将来成为该语言的一部分。

result_of需要一个调用表达式,从中推导出返回类型。

修复这两个问题,您的代码变为

template<typename F>
auto call(F const& f) -> typename std::result_of<decltype(f)()>::type
//                    or typename std::result_of<F()>::type
{
  return f();
}

或者你可以使用

template<typename F>
auto call(F const& f) -> decltype(f())
{
  return f();
}

Live demo


我认为如果你修复result_of表达式,你的原始代码应该编译,但它不在gcc-4.9或5.0上;也许这是gcc扩展的错误,它允许参数类型为auto

// This fails to compile
auto call3(const auto& f) -> typename std::result_of<decltype(f)()>::type
{
  return f();
}

答案 1 :(得分:2)

这不是你拨打std::result_of的方式,它应该是:

auto call(const auto& f) -> typename std::result_of<decltype(f)()>::type
{
  return f();
}

或者甚至更简单,你可以写:

auto call(const auto& f) -> decltype(f())
{
  return f();
}

答案 2 :(得分:-3)

功能参数AS&#39; auto&#39;自c ++ 14 / c ++ 1y 以来支持 &LT;更简单的解决方案&gt;
这里的问题是汽车将被认为是相同的类型[由语言标准决定 - HATERS将会说BUG ]。

解决方案:

1)&#39; - &gt;&#39;从c ++ 14开始,返回类型根本不需要,因为funcion调用只有一个return语句。

2)要克服所有汽车政策的相同类型[auto:1,auto:2,...],LETS GO VARIADIC

3)明确检查单个参数。

#include <initializer_list>

auto call(const auto&... f)
{
    static_assert(sizeof...(f)==1,"Exactly 1 argument should be provided");
    return std::begin({f...})[0]();   // black magic : to call first arg of singleton pack
}


int main()
{
    return call([] {return 0;});
}

希望它能解决你的问题。 注意:在TDM GCC 4.9.2中测试,cygwin gcc 5.0

应该用-std = c ++ 14编译或-std = c ++ 1y