如何获取泛型 lambda 的返回类型和参数类型?

3
我想获取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的返回类型和参数类型的问题呢?


请勿编辑问题以使现有答案无效。相反,请发布一个新问题。 - xskxzr
两种变体都无法编译,第一种情况会导致 lambda 对象被强制转换为函数指针。 - Swift - Friday Pie
2个回答

3

泛型lambda是指其operator()重载为模板函数的lambda表达式。如果一个模板函数的参数被推导出,那么它没有类型;只有这个模板的单独实例化具有带有类型的参数。

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


现在我对如何判断一个函数是否为模板函数感到困惑... - haskeller
在这种情况下,您的“auto” lambda表达式并没有完全定义。只有当自动类型被推断出时,它才会被定义。 - David Ledger
谢谢。那么从通用的 lambda 表达式中获取参数数量是不可能的吗? - haskeller
@haskeller 因为通用 lambda 是带有模板 operator() 的 lambda,所以当 f2 是一个通用 lambda 时,decltype(f2) 是非法的表达式,因为没有使用任何参数。 - Swift - Friday Pie

1

lambda表达式并不是函数。

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

一些lambda表达式具有隐式转换运算符,可以转换为函数指针。

这里是cppinsights中这两个的样子链接

顺便说一句,如果您是C++模板新手,我强烈建议使用cppinsights这里有一个很棒的视频讲解它,以及这里有一个使用cppinsights深入探讨lambda表达式。

此处是您的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 具有模板调用运算符,但没有隐式转换运算符-因为调用运算符是成员函数模板。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接