如果一个对象被声明为const
,则其值保证仅在运行时可用,但如果它被声明为constexpr
,则该值保证在编译期间和运行时都可用。因此,如果我有一个在编译期间值可用的对象,是否有任何我不应该声明它的情况constexpr
?
const int magicValue = 42; // Does this ever make sense
// (using const instead of constexpr)?
对于函数,如果函数可以返回编译期间计算的值,当在编译期间传递带有值的参数时,是否有意义不声明函数constexpr
?
struct Point { int x; int y; };
Point midPoint(Point p1, Point p2) // Does this ever make
{ // sense (not declaring
return { (p1.x + p2.x) / 2 , (p1.y + p2.y) / 2 }; // the function
} // constexpr)?
我能想到的唯一情况是当你不想提交能够在使用known-at-compile-time参数调用时计算编译时常量的函数,例如,如果你想保留在不改变其界面的情况下灵活地改变midPoint
的实现(从而可能破坏调用者)。例如,您可能希望保留向constexpr
添加非midPoint
副作用的灵活性,例如IO。
答案 0 :(得分:4)
对于变量,我认为没有理由不使用constexpr
。但并非总是可以这样做,例如当变量的初始化器由虚函数计算时,例如
向函数添加constexpr
是界面更改:您表示可以使用它来初始化constexpr
变量。这会对函数的实现施加约束,例如不调用虚函数,不调用动态内存,也不将lambda函数作为函数对象。
请注意,LWG issue 2013的解析不允许标准库的实施者自由地将constexpr
添加到库函数中。其中一个原因是声明函数constexpr
可以禁止执行动态分配的某些调试实现(特别是迭代器检查)。这意味着未来constexpr
对标准库的扩展需要是单独的提案。这与noexcept
形成鲜明对比,在{{1}}中,图书馆作家有更多的自由。
答案 1 :(得分:0)
你可以更改const:
int const x = 1;
*const_cast<int *>(&x) = 5;
你不能对constexpr做同样的事情,它允许编译器知道,毫无疑问表达式在编译时可用,因此可以进行优化。