为何该表达式非常量表达式?对应[expr.const]/5哪一条款?
问题分析与解答
示例代码
struct S { const bool x = true; constexpr const bool& f() { return x; } } s{}; int main() { static_assert(s.f()); // 错误:s未被声明为'constexpr' }
问题背景
这个问题和《How to make this pointer constant expression》重复,原因是表达式 E = s.f() 未执行左值到右值转换([expr.const]/(5.8));但和《How to get std array size in a constant expression》不重复,因为表达式 E = s.f() 在作为求值环节一部分的constexpr函数 S::f 中,对 this 进行了求值操作([expr.const]/(5.1))。
核心问题:上述示例适用[expr.const]/5中的哪一项规则(如果有的话)?
解答
这个示例同时涉及[expr.const]/5下的两条规则:
- [expr.const]/5.1:表达式求值过程中包含对非constexpr对象的
this指针的求值。这里S::f是constexpr成员函数,调用s.f()时,函数内部的this指向全局对象s,但s并未被声明为constexpr对象。常量表达式求值不允许对非constexpr对象的this指针进行求值,这是触发错误的直接原因。 - [expr.const]/5.8:表达式求值过程中包含对非constexpr对象的左值到右值转换。虽然
E = s.f()本身未执行该转换,但static_assert(s.f())中需要将s.f()返回的左值引用转换为右值以获取true的数值,而该引用绑定的是s.x——非constexpr对象的成员,这种转换同样不符合常量表达式的要求。
编译器给出的错误提示s is not declared as 'constexpr',主要对应[expr.const]/5.1的规则:因为constexpr函数f中使用了指向非constexpr对象s的this指针,导致整个s.f()表达式无法成为有效的常量表达式。
内容的提问来源于stack exchange,提问作者mada
相关产品推荐
相关产品推荐

