【问题标题】:Can I deduce the return type of a lambda without actually calling it?我可以在不实际调用它的情况下推断出 lambda 的返回类型吗?
【发布时间】:2014-05-26 15:41:32
【问题描述】:

这对某些人来说似乎很明显,但我仍然想知道:有没有办法让编译器在不实际调用的情况下推断出 lambda 返回类型?

当然你可以auto retval = myLambda();,不过我想要这样的东西:

T_MY_LAMBDA_RETVAL retval;
...
retval = myLambda();

我为什么要那个?简单:

try {
    auto retval = myLambda();
catch (exception e) {
    ...
}

// retval is undefined but I wonna have it!!! :)

【问题讨论】:

  • // retval is undefined but I wonna have it!!! :)。什么。您究竟想如何访问超出其范围的变量?
  • @William Andrew Montgomery:显然是通过转发声明 retval 这是我问题的全部目的。

标签: c++11 lambda type-deduction


【解决方案1】:
typedef typename std::result_of<decltype(lambda)()>::type return_type;

推导出使用 0 个参数调用 lambda 的返回类型。

照样:

typedef decltype( lambda() ) return_type;

小心可能的右值引用。

【讨论】:

    【解决方案2】:

    完成Yakk的回答

    与:

    auto myLambda = [&](int) { return 42; }; // Or any lambda
    

    你可以使用

    using T_MY_LAMBDA_RETVAL = std::result_of<decltype(myLambda)(int)>::type;
    

    using T_MY_LAMBDA_RETVAL = decltype(myLambda(std::declval<int>()));
    

    然后使用它:

    T_MY_LAMBDA_RETVAL retval;
    try {
        retval = myLambda(42);
    catch (exception& e) {
        // ...
    }
    // you may use retval which may be uninitialized.
    

    【讨论】:

      【解决方案3】:

      一个 lambda 表达式创建一个独特的函子类型,它重载 operator(),这是当你调用 lambda 时被调用的。我们可以利用这个事实来判断 lambda 表达式的返回类型。

      template<typename T>
      struct lambda_traits_helper;  // undefined
      
      // specialize for pointer to member function
      template<typename T, typename Result, typename... Args>
      struct lambda_traits_helper<Result(T::*)(Args...) const>
      {
          using result_type = Result;
      };
      
      template<typename Func>
      struct lambda_traits 
          : lambda_traits_helper<decltype(&Func::operator())>
          // instantiate helper trait with pointer to operator()
      {};
      

      示例用法:

      auto lambda = []{ return 42; };
      assert((std::is_same<int, lambda_traits<decltype(lambda)>::result_type>::value));
      
      auto lambda = [](int a){ return std::to_string(a); };
      assert((std::is_same<std::string, lambda_traits<decltype(lambda)>::result_type>::value));
      

      Live demo

      【讨论】:

      • 在 C++1y 中 auto lambda = []( auto&amp;&amp; x ) { return x; }; 会导致这种技术出现问题,所以我建议不要这样做。
      猜你喜欢
      • 2013-10-18
      • 2021-05-13
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 2019-05-06
      相关资源
      最近更新 更多