lambda作为静态成员

Pau*_* II 27 c++ lambda language-lawyer constexpr c++11

我正在尝试使用lambda作为静态成员,如下所示:

struct A
{
    static constexpr auto F = [](){};
};


int main()
{
    A::F();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是否是正确的C++ 11代码?在clang上,我收到此错误:

error: constexpr variable 'F' must be initialized by a constant
      expression
    static constexpr auto F = [](){};
                              ^~~~~~
Run Code Online (Sandbox Code Playgroud)

似乎在铿锵声中,lambdas不被视为常数表达.它是否正确?也许他们还没有在clang中完全实现lambdas,因为gcc 4.7似乎允许它作为a constexpr,但是它给出了另一个错误:

error: ‘constexpr const<lambda()> A::F’, declared using local type ‘const<lambda()>’, is used but never defined
Run Code Online (Sandbox Code Playgroud)

我不确定,我明白这意味着什么.它似乎正确地推断出lambda的类型,但它只声明它而不是定义它.我该如何定义它?

Ric*_*ith 17

此代码格式错误.甲constexpr需要变量由常量表达式被初始化,并且[expr.const]p2表示:

条件表达式是一个核心常量表达式除非它涉及以下作为一个潜在的评价子表达式中的一个[...]:

  • 一个lambda表达式

因此,GCC接受此代码是不正确的.

这是为类提供lambda类型的静态数据成员的一种方法:

auto a = []{};
struct S {
  static decltype(a) b;
};
decltype(a) S::b = a;
Run Code Online (Sandbox Code Playgroud)

  • @LucDanton常量表达式是根据核心常量表达式定义的,因此p2是相关的.见p3."常量表达式"和"核心常量表达式"的不同不是"语法"与"语义",但据我记忆所知,"实际编译时已知值或引用"与"计算常量表达式的中间结果" ".因此,非静态局部变量的地址是有效的核心常量表达式.但由于该地址的值在编译时并不是真正知道的,因此它不是地址常量表达式. (2认同)
  • @Paul我觉得你运气不好.有一些技巧可以在模板中获取lambda表达式并提取其类型,例如`template <typename T> std :: remove_reference <T> :: type*addr(T && t){return&t; } struct S {constexpr static auto*p = false?addr([] {}):nullptr; static decltype(*p)lambda; 但是,即使这样,也不可能为`S :: lambda`提供初始化器. (2认同)