为何返回非静态数据成员的成员函数调用不属核心常量表达式?
为什么
s.f()是核心常量表达式而s.g()不是? 关键差异点
s.f()的情况:f()返回的是类的静态成员变量x。静态成员属于类本身,和具体的对象实例无关。调用s.f()时,编译器不需要读取对象s的任何状态,直接就能确定x的值是true,因此整个表达式可以在编译期计算,属于核心常量表达式。s.g()的情况:g()返回的是对象s的非静态成员变量y。非静态成员属于对象实例,要获取y的值必须访问对象s的内存。但这里的s只是被声明为const,并没有被标记为constexpr——非constexpr的对象无法在常量表达式中被用来访问其非静态成员,所以s.g()不能成为核心常量表达式。
C++标准中的对应规则
根据C++标准的**[expr.const]**章节(常量表达式的定义):
核心常量表达式中,不能包含对非
constexpr对象的非静态成员的访问,除非该对象是在常量表达式内部创建的临时对象,或者对象的生命周期始于常量表达式内部。
在示例代码里,s是在main函数中声明的普通const对象,不属于上述例外情况,因此访问它的非静态成员y会导致表达式不符合核心常量表达式的要求,最终触发static_assert的错误。
示例代码与错误信息
示例代码:
struct S { static bool const x = true; const bool y = true; constexpr bool f() const { return x; } constexpr bool g() const { return y; } }; int main() { const S s{}; static_assert(s.f()); // OK static_assert(s.g()); // error }
g++ trunk给出的错误信息:
error: non-constant condition for static assertion static_assert(s.g());
error: the value of 's' is not usable in a constant expression
note: 's' was not declared 'constexpr'
内容的提问来源于stack exchange,提问作者mada
相关产品推荐
相关产品推荐

