【问题标题】:How to detect whether a type is a lambda expression at compile time?如何在编译时检测类型是否为 lambda 表达式?
【发布时间】:2011-12-12 22:44:55
【问题描述】:

假设我有一个类型my_struct 包含一个成员变量f,它是一个函数。 f 有可能是一个 c++11 的 lambda 函数。

由于分配给 lambda 对象是非法的,我想以这样一种方式实现my_struct 的赋值运算符,当f 是一个 lambda 时,它不会被分配。

是否可以构建一个类型特征is_lambda 来检查类型的 lambda 特性?

在代码中:

#include <type_traits>

template<typename Function> struct is_lambda
{
  // what goes here?
};

template<typename Function> struct my_struct
{
  Function f;

  my_struct &do_assign(const my_struct &other, std::true_type)
  {
    // don't assign to f
    return *this;
  }

  my_struct &do_assign(const my_struct &other, std::false_type)
  {
    // do assign to f
    f = other.f;
    return *this;
  }

  my_struct &operator=(const my_struct &other)
  {
    return do_assign(other, typename is_lambda<Function>::type());
  }
};

【问题讨论】:

    标签: c++ lambda template-meta-programming


    【解决方案1】:

    没有编译器支持是不可能的,因为 lambda 的类型只是普通的非联合类类型。

    §5.1.2 [expr.prim.lambda] p3

    lambda-expression 的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型 [...]

    【讨论】:

      【解决方案2】:

      大概您也不想分配不可分配的非 lambda 函数,因此您可以使用 std::is_assignable

      【讨论】:

      • 这似乎在 Visual C++ 2015 中工作,也许在早期版本中也是如此。简单地使用:std::is_assignable&lt;decltype(lam). decltype(lam)&gt;::value。我使用这种方法来确保在使用 EBO 时不会派生 lambda。
      • @MatthewHolder 这有点错过了我的回答,那就是你不应该尝试给 lambdas 特殊待遇。从 lambda 派生本身并没有错。它有一些可能使它变得棘手的方面,但这些相同的方面可以应用于非 lambda 类。它们不可分配的事实不是其中之一,所以在你的情况下,我认为这不是应该检查的方面。
      • 可以理解,但需要我检测 lambda 的情况是,将 FunctionObject 传递给将用作空基优化的类模板的基类的类模板类型参数时。因为您不能在某些情况下或某些编译器上继承 lambda 类型。随着这种情况的改善......这将不再是一个问题。
      • @MatthewHolder 这仍然没有抓住重点。您应该检测是否可以将该类型用作基类。非类类型不能从其中任何一个派生。最终类不能从任何一个派生。在编译器不允许从 lambda 派生的情况下,检测您是否可以从该类型派生应该已经涵盖 lambda 以及所有其他场景。在编译器确实允许从 lambda 派生的情况下,检测您是否可以从该类型派生可以防止误报。
      猜你喜欢
      • 2017-06-10
      • 1970-01-01
      • 2011-01-08
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多