为什么静态lambda成员的封闭类型不完整?

Gui*_*cot 15 c++ lambda language-lawyer c++17

我今天尝试做类似的事.我很惊讶它没有编译.

struct Test {
//  v----- Remove me to compile
    //  /*
    static constexpr auto get_test1 = [](Test const& self) {
        return self.test; // error, Test is incomplete
    };
    // */

    // Handwritten version of the lambda
    struct {
        constexpr auto operator() (Test const& self) const {
            return self.test; // ok
        }
    }
    static constexpr get_test2{};

    int test;
};
Run Code Online (Sandbox Code Playgroud)

实例

它说Test范围内的类型不完整.然而,lambda的手写版确实有效.这是什么技术原因?这是标准中的疏忽,还是有一个特定的措辞Test在lambda中不完整?

bol*_*lov 3

这是我能找到的:

\n\n
\n

\xc2\xa75.1.2 Lambda 表达式 [expr.prim.lambda]

\n\n
    \n
  1. [...] [ 注意: lambda 声明符中引用的名称在 lambda 表达式出现的上下文中查找。\xe2\x80\x94结束注]

  2. \n
  3. lambda 表达式\xe2\x80\x99s 复合语句生成函数调用运算符的函数体 (8.4),但出于名称查找\n (3.4) 的目的,[...] 复合语句被视为在 lambda 表达式的上下文中。

  4. \n
\n
\n\n

如果我没有误读标准,这意味着参数Test以及self主体中的内容都是在 lambda 的上下文中查看/考虑的,这是其中的类范围Test不完整的类范围。

\n\n

至于为什么嵌套类允许这样做:

\n\n
\n

\xc2\xa79.2 类成员 [class.mem]

\n\n
    \n
  1. 在类说明符的结尾 } 处,类被视为完全定义的对象类型 (3.9)(或完整类型)。在类成员规范中,类在函数体、默认参数、引入继承构造函数 (12.9)、异常规范和大括号或等于的声明中被视为完整的。非静态数据成员的初始值设定项(包括嵌套类中的此类内容)。否则,在其自己的类成员规范中,它被视为不完整。
  2. \n
\n
\n