非const成员函数上使用constexpr的作用是什么?
非const成员函数上使用constexpr的作用与C++14中的关键细节
嘿,这个问题问到点子上了!咱们一步步把它讲明白:
非const成员函数加constexpr的核心作用
简单来说,constexpr修饰非const成员函数,就是允许这个函数在编译期被调用——但有个前提:调用它的对象得是编译期可见的(比如是constexpr修饰的对象,或者在编译期语境里构造的对象)。
这里最容易踩坑的点是:constexpr不代表这个函数不会修改对象!这和const成员函数的语义完全不同,很多人会把这俩搞混。
用实际例子看C++14里的差异
咱们看那个经典的编译错误示例:
struct A { constexpr A() {} constexpr int a() {return 12; } // 非const的constexpr成员函数 constexpr int b() const {return 12; } // const的constexpr成员函数 }; int main() { constexpr A a; // 这里编译失败! }
为啥会编译失败?原因其实很直白:
- 当你声明
constexpr A a时,这个对象是默认带有const属性的编译期常量对象。 - 在C++14中,编译器会检查:这个const对象是否能安全地被所有
constexpr成员函数调用。但你的类里有个非const的constexpr成员函数a()——const对象根本没法调用非const成员函数,哪怕这个函数实际上没修改任何状态,编译器也会判定这个类的constexpr对象不符合要求,直接报错。
如果把a()改成const版本,或者删掉这个非const的constexpr函数,constexpr A a就能正常编译通过了。
再划一遍重点
- 非const成员函数的
constexpr:解锁编译期调用能力,允许修改对象(只要函数逻辑里这么写了),只能被非const的constexpr对象调用。 - const成员函数的
constexpr:既解锁编译期调用,又保证函数不修改对象,能被const/非const的constexpr对象调用。
内容的提问来源于stack exchange,提问作者Michael Anderson
相关产品推荐
相关产品推荐

