代码链接见:https://wandbox.org/permlink/ksQk5KCf4K5ChUe0
constexpr(常量表达式)是为了解决C++历史遗留问题,它一种比const 更严格的束缚, 它规定了表达式本身在编译期间可知。简单来说,const其实是readonly(只读),而constexpr才是const(常量)。二者更多区别见:知乎:C++ const 和 constexpr 的区别?
在C++11标准中,不允许常量表达式作用于virtual的成员函数,因为virtual表示的是运行时的行为,这与constexpr“可以在编译时期进行计算”的意义是冲突的。“在编译时期进行计算”是对编译器的一个建议,C++11标准并没有强制要求编译器一定要在编译时期对常量表达式函数进行计算。
但从C++20开始, constexpr 可以修饰虚函数,使得虚函数可以在编译期被计算出。constexpr虚函数可以继承非constexpr虚函数,反之亦然。
代码如下:
// gcc >=10,
// g++ test.cpp -Wall -Wextra -std=c++2a
#include <iostream>
using namespace std;
struct X1 {
virtual int f() const = 0;
};
struct X2: public X1 {
constexpr virtual int f() const { return 2; }
};
struct X3: public X2 {
virtual int f() const { return 3; }
};
struct X4: public X3 {
constexpr virtual int f() const { return 4; }
};
int main()
{
constexpr X4 x4;
constexpr int res = x4.f(); // == 4
std::cout << "res is: " << res;
return 0;
}