0 结论
constexpr 对象都具备const 属性,并由编译期已知的值完成;constexpr 函数在调用时若传入的实参值是由编译期已知的,则会产出编译期结果;- 比起非
constexpr 对象或constexpr 函数而言,constexpr 对象或是constexpr 函数可以用在一个作用域更广的语境中。
1 优势
constexpr 是在翻译时期(编译、链接时期)就已知。在编译时期就已知的值,拥有许多特权。
- 比如,可能被放到只读内存中(对于嵌入式工程师很有用);
- 在编译阶段就已知的常量整形值可以用在C++要求整形常量表达式的语境中,这些语境包括数据的尺寸规格、整形模版实参(包括
std::array 类型对象的长度)、枚举变量的值、对齐规格等; - 在调用
constexpr 函数时,若传入的值有一个或多个在编译期未知,则它的运作方式和普通函数无异(在运行期间执行结果计算);如果用在编译期间常量语境,任何一个实参值在编译期未知,则代码无法通过编译【这意味着constexpr 可以用在要求编译期常量和所有其他值的情况】 - 运行期完成的工作迁到编译期越多,软件运行的越快。
2 注意点
所有constexpr 都是const 对象,而非所有的const 对象都是constexpr 对象。
int x;
constexpr auto arraySize = 10;
std::array<int, arraySize> data;
const auto arraySize2 = x;
C++11中限制:
- 仅限于传入和返回字面型别【在编译期就可以决议的值】,所有内建类型,除了void都符合这个条件;
constexpr 函数不得包含大于一个可执行的语句;- 成员函数不能修改非
mutable 数据成员。
这些限制在C++14中都被移除了。
class Point{
public:
constexpr Point(){}
constexpr Point(double xVal, double yVal) noexcept:m_x(xVal), m_y(yVal){}
constexpr double xValue() const noexcept{return m_x;}
constexpr double yValue() const noexcept{return m_y;}
constexpr void setX(double newX) noexcept{m_x = newX;}
constexpr void setY(double newY) noexcept{m_y = newY;}
private:
double m_x, m_y;
};
constexpr Point reflection(const Point& p) noexcept{
Point result;
result.setX(-p.xValue());
result.setY(-p.yValue());
return result;
}
int main(){
constexpr Point p(9.2, 27.7);
constexpr auto reflect = reflection(p);
return 0;
}
|