constexpr 变量
声明为 constexpr 的变量隐式为 const,其值可用作常量表达式。
与 #define 的比较
constexpr 是基于 #define 的编译时表达式的类型安全替代品。使用 constexpr,编译时计算的表达式将替换为结果。例如:
Version >= C++ 11
int main()
{
   constexpr int N = 10 + 2;
   cout << N;
}
将产生以下代码:
cout << 12;
基于预处理器的编译时宏将是不同的。考虑:
#define N 10 + 2
int main()
{
    cout << N;
}
将产生:
cout << 10 + 2;
这显然会转换为 cout << 10 + 2;。但是,编译器必须做更多的工作。此外,如果使用不正确,也会产生问题。
例如(使用 #define):
cout << N * 2;
形式:
cout << 10 + 2 * 2; // 14
但是预先评估的 constexpr 会正确地给出 24。
与 const 的比较
const 变量是一个需要内存的变量。一个 constexpr 没有。constexpr 产生编译时常量,不能改变。你可能会说,const 也可能不会改变。但请考虑:
int main()
{
   const int size1 = 10;
   const int size2 = abs(10);
   int arr_one[size1]; 
   int arr_two[size2]; 
}
对于大多数编译器,第二个语句将失败(例如,可能与 GCC 一起使用)。你可能知道,任何数组的大小都必须是常量表达式(即导致编译时值)。第二个变量 size2 被分配了一些在运行时决定的值(即使你知道它是 10,对于编译器来说它不是编译时)。
这意味着 const 可能是也可能不是真正的编译时常量。你不能保证或强制执行特定的 const 值绝对是编译时。你可以使用 #define 但它有自己的陷阱。
因此,只需使用:
Version >= C++ 11
int main()
{
    constexpr int size = 10;
    int arr[size];
}
constexpr 表达式必须求值为编译时值。因此,你不能使用:
Version >= C++ 11
constexpr int size = abs(10);
除非函数(abs)本身返回一个 constexpr。
所有基本类型都可以使用 constexpr 进行初始化。
Version >= C++ 11
constexpr bool FailFatal = true;
constexpr float PI = 3.14f;
constexpr char* site= "StackOverflow";
有趣的是,你也可以方便地使用 auto:
Version >= C++ 11
constexpr auto domain = ".COM";  // const char * const domain = ".COM"
constexpr auto PI = 3.14;        // constexpr double