3 回答
TA贡献1818条经验 获得超11个赞
我相信存在差异。让我们重命名它们,以便我们可以更容易地讨论它们:
const double PI1 = 3.141592653589793;
constexpr double PI2 = 3.141592653589793;
这两个PI1和PI2是不变的,这意味着你不能修改它们。但是只有 PI2编译时常量。它应在编译时初始化。 PI1可以在编译时或运行时初始化。此外,只能 PI2在需要编译时常量的上下文中使用。例如:
constexpr double PI3 = PI1; // error
但:
constexpr double PI3 = PI2; // ok
和:
static_assert(PI1 == 3.141592653589793, ""); // error
但:
static_assert(PI2 == 3.141592653589793, ""); // ok
至于你应该使用哪个?使用符合您需求的任何一种。您是否希望确保您具有可在需要编译时常量的上下文中使用的编译时常量?您是否希望能够在运行时进行计算来初始化它?等等。
TA贡献1909条经验 获得超7个赞
这里没有区别,但是当你有一个具有构造函数的类型时,这很重要。
struct S {
constexpr S(int);
};
const S s0(0);
constexpr S s1(1);
s0是一个常量,但它不承诺在编译时初始化。s1是标记的constexpr,所以它是一个常量,因为它S的构造函数也被标记constexpr,它将在编译时初始化。
大多数情况下,这很重要,因为在运行时初始化会非常耗时,并且您希望将该工作推送到编译器上,这也很耗时,但不会减慢编译程序的执行时间
TA贡献1895条经验 获得超7个赞
constexpr表示编译期间常量且已知的值。
const表示一个仅为常数的值; 在编译期间不必知道。
int sz;
constexpr auto arraySize1 = sz; // error! sz's value unknown at compilation
std::array<int, sz> data1; // error! same problem
constexpr auto arraySize2 = 10; // fine, 10 is a compile-time constant
std::array<int, arraySize2> data2; // fine, arraySize2 is constexpr
请注意,const不提供与constexpr相同的保证,因为const对象无需使用编译期间已知的值进行初始化。
int sz;
const auto arraySize = sz; // fine, arraySize is const copy of sz
std::array<int, arraySize> data; // error! arraySize's value unknown at compilation
所有constexpr对象都是const,但并非所有const对象都是constexpr。
如果您希望编译器保证变量的值可以在需要编译时常量的上下文中使用,那么要实现的工具是constexpr,而不是const。
- 3 回答
- 0 关注
- 798 浏览
添加回答
举报