繁体   English   中英

Class type undefined in static member lambda function in C++17

[英]Class type undefined in static member lambda function in C++17

不久前,我试图实现自己的 v-tables(用于教育目的)。 为此,我使用了 function 指针和 lambda。 在这样做的过程中,我偶然发现了一个问题。 我没有发布整个 v-table 代码,而是编写了一个 Minimal Reproducible Example。

由于某种原因,它无法编译(C2027 - 使用未定义类型测试):

class Test
{
    int n;
    static inline auto f = [](Test* t)
    {
        return t->n;
    };
};

即使我像这样前向声明Testclass Test; .

我很好奇是什么导致了这种行为,因为int nclass Test都是在 lambda 之前声明的。

我正在使用带有 C++17 的最新 Visual Studio 2019。

Testlambda之前声明,但未定义 class 定义仅在 class 本身的末尾完成,当您执行}; . 在那之前,它是一个不完整的类型。

而且您不能访问不完整类型的成员。 或者至少,不是通过 object 实例,就像您在 lambda 中所做的那样(此时您可以谈论Test::n ,但您不能参加Test*并对其执行->n操作)。

现在,您可能会说,如果您创建了一个普通的f成员,您可以轻松地将 class 的定义放在那里并且它会起作用。 这是因为 C++ 对 class 的成员函数的定义有一个特殊规则。 即,这些函数的主体被认为是被定义为就好像它们被放置在 class 定义之后一样。 因此,他们可以在内部使用 class,就好像它是一个完整类型一样,因为这些 function 主体将在它们是完整类型的地方定义。

您的 lambda 不是 function 的成员; 这是一个 lambda function 被分配给一个类静态变量。 static 变量的初始化程序没有得到这种特殊处理,因此在 lambda 的 function 主体内部, Test被认为是不完整的。

您不能这样做,因为 class 在 lambda 表达式的点上还不是一个完整的类型。

[类.mem]

6 class 的完整类上下文是

  • function 主体([dcl.fct.def.general]),

  • 默认参数,

  • noexcept 说明符,或

  • 默认成员初始化器

在 class 的成员规范内。 [ Note: A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested class is defined within the member-specification of the enclosing class. ——尾注]

7 A class 在类说明符的结束处被视为完全定义的 object 类型([basic.types])(或完整类型)。 class 在其完整类上下文中被认为是完整的; 否则,它在其自己的 class 成员规范中被视为不完整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM