2

我想获取 lambda 的返回类型和参数类型。 是否可以确定 lambda 的参数类型和返回类型?给出一个解决方案。但它不适用于通用 lambda。

template<typename F>
struct function_traits :public
    function_traits<decltype(&F::operator())> {};

template<typename R,typename C,typename... Args>
struct function_traits<R(C::*)(Args...)const>:public
    function_traits<R(Args...)>{
  constexpr static size_t arity = sizeof...(Args);
};

auto f1 = [](int x) {return x+1; };
Print(function_traits<decltype(f1)>::arity);  //return 1
auto f2 = [](auto x) {return x+1; };
Print(function_traits<decltype(f2)>::arity);  //error

那么如何解决它来获取泛型 lambda 的返回类型和参数类型呢?

4

2 回答 2

3

通用 lambda 是 lambda,其中operator()重载是模板函数。如果推导出模板函数的参数,则它没有类型;只有此类模板的单独实例具有类型的参数。

auto不是类型;它是一个占位符,表示“这是一个模板参数”。

于 2020-04-01T06:53:21.917 回答
1

Lambda 无论如何都不是函数。

编译器将f1f2视为具有调用运算符的类。

一些 lambda 具有到函数指针的隐式转换运算符。

这是一个链接到这两个在 cppinsights 中的样子。

顺便说一句,如果您不熟悉 C++ 模板 ,我强烈建议您使用cppinsights 。这是一个关于它的精彩视频,这是他使用 cppinsights 深入探索 lambdas 的视频。

我还在这里复制了相关代码进行解释,以防链接消失。

这就是你的f1样子。

class __lambda_1_11
{
  public: 
  inline /*constexpr */ int operator()(int x) const
  {
    return x + 1;
  }

  using retType_1_11 = int (*)(int);
  inline /*constexpr */ operator retType_1_11 () const noexcept
  {
    return __invoke;
  };

  private: 
  static inline int __invoke(int x)
  {
    return x + 1;
  }
};

这就是你的f2样子。

class __lambda_2_11
{
  public: 
  template<class type_parameter_0_0>
  inline /*constexpr */ auto operator()(type_parameter_0_0 x) const
  {
    return x + 1;
  }
  private: 
  template<class type_parameter_0_0>
  static inline auto __invoke(type_parameter_0_0 x)
  {
    return x + 1;
  }
};

请注意,它f1有一个非模板调用运算符,并且它有一个到函数指针 ( int (*)(int)) 的隐式转换运算符。

f2有一个模板调用操作符并且没有一个隐式转换操作符——因为调用操作符是一个成员函数模板。

于 2020-04-01T12:36:28.877 回答