常量vs constexpr上的variables

以下定义有区别吗?

const double PI = 3.141592653589793; constexpr double PI = 3.141592653589793; 

如果不是,在C ++ 11中哪种风格是首选?

我相信有一个区别。 让我们重新命名它们,以便我们可以更轻松地谈论它们:

 const double PI1 = 3.141592653589793; constexpr double PI2 = 3.141592653589793; 

PI1PI2都是恒定的,这意味着你不能修改它们。 但是, 只有 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 

至于你应该使用哪个? 使用符合您的需求的任何一个。 你想确保你有一个编译时间常量,可以在需要编译时常量的上下文中使用吗? 你想能够在运行时进行计算来初始化它吗? 等等。

这里没有什么区别,但是当你有一个具有构造函数的types时,它就很重要。

 struct S { constexpr S(int); }; const S s0(0); constexpr S s1(1); 

s0是一个常量,但不保证在编译时被初始化。 s1被标记为constexpr ,所以它是一个常量,因为S的构造函数也被标记为constexpr ,它将在编译时被初始化。

大多数情况下,在运行时进行初始化将非常耗时,而且您希望将这些工作推送到编译器上,这同样很耗时,但不会减慢编译程序的执行时间

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。

如果你希望编译器保证一个variables的值可以在需要编译时常量的上下文中使用,那么要达到的工具是constexpr,而不是const。

一个constexpr符号常量必须被赋予一个在编译时已知的值。 例如:

 constexpr int max = 100; void use(int n) { constexpr int c1 = max+7; // OK: c1 is 107 constexpr int c2 = n+7; // Error: we don't know the value of c2 // ... } 

为了处理一个“variables”的值,该variables的初始值是在编译时不知道的,但在初始化后永远不会改变,C ++提供了第二种forms的常量( const )。 例如:

 constexpr int max = 100; void use(int n) { constexpr int c1 = max+7; // OK: c1 is 107 const int c2 = n+7; // OK, but don't try to change the value of c2 // ... c2 = 7; // error: c2 is a const } 

这种“ 常量variables”非常普遍,原因有二:

  1. C ++ 98没有constexpr,所以人们使用const
  2. 列表项“variables”不是常量expression式(它们的值在编译时是未知的),但在初始化后不改变值本身是非常有用的。