不能在 class 范围内将 `static_assert` 与 `sizeof` 一起使用(但方法范围是可以的)
Cannot use `static_assert` with `sizeof` inside class scope (but method scope is okay)
这是一个简单示例的摘录(参见 full source live here):
class Foo final {
public:
int var;
inline Foo(void) {
static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
}
static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
};
在最近的 g++ 中(N.B。MSVC 没有抱怨),这会产生如下内容:
error: invalid application of ‘sizeof’ to incomplete type ‘Foo’
该错误仅在 发生在第二个 static_assert
。
我知道 class 的定义还没有写完 词法 ,但是完整类型的所有信息肯定都在那里,对吧?我的意思是,我们 在 里面。即使不是,为什么它会在方法中起作用?
class 类型在它自己的成员函数体内是完整的(正如 Matt 所说,函数体的处理是延迟的)。 class 定义的 {}
内的大多数其他地方都不完整,包括 static_assert
。第 9.2 节的规则是
A class is considered a completely-defined object type (or complete type) at the closing }
of the class-specifier. Within the class member-specification, the class is regarded as complete within function
bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and
brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
想一想,编译器应该怎么知道你没有
int another_var;
紧接在 static_assert
之后?
static_assert
的最佳位置可能就在 class 定义之后,在命名空间范围内。
这是一个简单示例的摘录(参见 full source live here):
class Foo final {
public:
int var;
inline Foo(void) {
static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
}
static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
};
在最近的 g++ 中(N.B。MSVC 没有抱怨),这会产生如下内容:
error: invalid application of ‘sizeof’ to incomplete type ‘Foo’
该错误仅在 发生在第二个 static_assert
。
我知道 class 的定义还没有写完 词法 ,但是完整类型的所有信息肯定都在那里,对吧?我的意思是,我们 在 里面。即使不是,为什么它会在方法中起作用?
class 类型在它自己的成员函数体内是完整的(正如 Matt 所说,函数体的处理是延迟的)。 class 定义的 {}
内的大多数其他地方都不完整,包括 static_assert
。第 9.2 节的规则是
A class is considered a completely-defined object type (or complete type) at the closing
}
of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
想一想,编译器应该怎么知道你没有
int another_var;
紧接在 static_assert
之后?
static_assert
的最佳位置可能就在 class 定义之后,在命名空间范围内。