[英]How to detect the existence of a function (NOT class member) with a specific name and signature using type_traits 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;
};
};
即使我像这样前向声明Test
: class Test;
.
我很好奇是什么导致了这种行为,因为int n
和class Test
都是在 lambda 之前声明的。
我正在使用带有 C++17 的最新 Visual Studio 2019。
Test
在lambda之前声明,但未定义。 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 表达式的点上还不是一个完整的类型。
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.