有没有应该避免constexpr的情况,即使它可以使用?

时间:2014-01-03 04:36:19

标签: c++ c++11 constexpr

如果一个对象被声明为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。

2 个答案:

答案 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做同样的事情,它允许编译器知道,毫无疑问表达式在编译时可用,因此可以进行优化。