为什么要声明一个constexpr

NoS*_*tAl 5 constexpr c++11

在观看isocpp.org上链接的C++ 11教程视频时,我注意到了一些事情:

constexpr int windowWidth{800}, windowHeight{600};
Run Code Online (Sandbox Code Playgroud)

声明这些int变量有什么意义constexpr,而不仅仅是const?

How*_*ant 6

好视频维托里奥!

以下是声明int const和之间区别的摘要constexpr:

int get_int();  // Some run time function that returns int

template <int N>  // example use requiring a compile time int
struct test {};

const     int w = get_int();  // initialized at run time
const     int x = 5;          // initialized at compile time
constexpr int y = get_int();  // error, can not initialize at compile time
constexpr int z = 6;          // initialized at compile time

int
main()
{
    test<w> tw;  // error, w is not a compile time constant
    test<x> tx;  // ok, x is a compile time constant
    test<y> ty;  // error, there is no compile time constant named y
    test<z> tz;  // ok, z is a compile time constant
}
Run Code Online (Sandbox Code Playgroud)

使用时constexpr,需要在编译时进行初始化,以免出现编译时错误.在使用时const,允许初始化在运行时发生,但如果初始化程序本身是编译时常量,它仍将在编译时发生.

如果你有const int,代码审查者必须查看初始化(如果这是a的副本,则返回原始版本const int),以了解它const int是编译时常量还是运行时常量.

如果你有constexpr int,代码审查者可以立即假设它是一个编译时常量,而不分析它是如何初始化的.如果该假设结果为假,则编译器会将其标记为错误.

<Disclaimer>

在下面的评论中,Kerrek SB正确地指出我在这个答案中用术语"快速而宽松".我这样做是为了使答案简短易懂.我所谓的"在编译时初始化"和"编译时间常量"是第5.19节"常量表达式"[expr.const]中的标准所指的整数常量表达式.

使用所谓的常量初始化初始化积分常量表达式,它与零初始化一起称为静态初始化([basic.start.init]/p2).

我在这里写的内容和标准中出现的内容之间的任何偏差都是偶然的,标准中的内容是正确的.

</Disclaimer>


Vit*_*meo 5

我是视频的作者.

意图.

constexpr清楚地表达了编译时不可变值的意图.const并不是指编译时不可变值.

两个修饰符都可以被转换,但这会导致未定义的行为.查看DyP的评论以获取更多信息.

当在我看来,使用C++ 11,编译时值打交道时应该想到的第一个关键词是没有 const,但constexpr.

代码在没有constexpr或const代替的情况下表现完全相同constexpr.但是当你看一下代码时,看到constexpr int windowWidth;你可以100%确定这是一个在运行时永远不会改变的不可变常量.


在我的第二个视频教程,有一个附录上constexpr的第一个三分钟,显示constexpr功能和更多constexpr的例子/解释.

  • *"`const`是一个甚至可以被转换的修饰符,因此它并不意味着编译时不可变值"*我认为`constexpr`实际上甚至不是对象类型的一部分,它只是意味着`const`并添加了对类型和初始化的限制.你可以从const声明的变量和constexpr声明的变量中抛弃constness; 通过这种非常量路径修改导致UB.重要的一点是*compile-time*:一个const声明的变量可以用一个只在运行时知道的值初始化,这与constexpr声明的变量不同. (3认同)