在观看isocpp.org上链接的C++ 11教程视频时,我注意到了一些事情:
constexpr int windowWidth{800}, windowHeight{600};
声明这些int
变量有什么意义constexpr
,而不仅仅是const
?
好视频维托里奥!
以下是声明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 }
使用时constexpr
,需要在编译时进行初始化,以免出现编译时错误.在使用时const
,允许初始化在运行时发生,但如果初始化程序本身是编译时常量,它仍将在编译时发生.
如果你有const int
,代码审查者必须查看初始化(如果这是a的副本,则返回原始版本const int
),以了解它const int
是编译时常量还是运行时常量.
如果你有constexpr int
,代码审查者可以立即假设它是一个编译时常量,而不分析它是如何初始化的.如果该假设结果为假,则编译器会将其标记为错误.
<Disclaimer>
在下面的评论中,Kerrek SB正确地指出我在这个答案中用术语"快速而宽松".我这样做是为了使答案简短易懂.我所谓的"在编译时初始化"和"编译时间常量"是第5.19节"常量表达式"[expr.const]中的标准所指的整数常量表达式.
使用所谓的常量初始化初始化积分常量表达式,它与零初始化一起称为静态初始化([basic.start.init]/p2).
我在这里写的内容和标准中出现的内容之间的任何偏差都是偶然的,标准中的内容是正确的.
</Disclaimer>
我是视频的作者.
意图.
constexpr
清楚地表达了编译时不可变值的意图.const
并不是指编译时不可变值.
两个修饰符都可以被转换,但这会导致未定义的行为.查看DyP的评论以获取更多信息.
当在我看来,使用C++ 11,编译时值打交道时应该想到的第一个关键词是没有 const
,但constexpr
.
代码在没有constexpr
或const
代替的情况下表现完全相同constexpr
.但是当你看一下代码时,看到constexpr int windowWidth;
你可以100%确定这是一个在运行时永远不会改变的不可变常量.
在我的第二个视频教程,有一个附录上constexpr
的第一个三分钟,显示constexpr
功能和更多constexpr
的例子/解释.