在观看C++11 tutorial video linked on isocpp.org时,我注意到了一些事情:
constexpr int windowWidth{800}, windowHeight{600};
将这些int
变量声明为constexpr
而不只是const
有什么意义?
答案 0 :(得分: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
}
当您使用constexpr
时,要求初始化在编译时发生,以免您收到编译时错误。使用const
时,允许初始化在运行时发生,但如果初始化程序本身是编译时常量,它仍将在编译时发生。
如果您有const int
,代码审核者必须查看初始化(如果这是const int
的副本,则返回原始版本)以了解const int
是否为constexpr int
编译时常量或运行时常量。
如果您有<Disclaimer>
,代码审阅者可以立即假设它是编译时常量而不分析它是如何初始化的。如果该假设结果为假,则编译器会将其标记为错误。
</Disclaimer>
在下面的评论中Kerrek SB正确地指出我在这个答案中使用术语“快速而宽松”。我这样做是为了使答案简短易懂。我所谓的“在编译时初始化”和“编译时间常量”是第5.19节“常量表达式”[expr.const]中的标准所指的整数常量表达式。
使用所谓的常量初始化初始化积分常量表达式,它与零初始化一起称为静态初始化([basic.start.init] / P2)。
我在这里写的内容和标准中出现的内容之间的任何偏差都是偶然的,标准中的内容是正确的。
{{1}}
答案 1 :(得分:5)
我是视频的作者。
<强>意图强>
constexpr
清楚地表达了编译时不可变值的意图。 const
并不意味着编译时不可变值。
两个修饰符都可以转出,但这会导致未定义的行为。查看DyP的评论以获取更多信息。
在使用C ++ 11时,在我看来,处理编译时值时应该首先考虑的第一个关键字是不是 const
而是constexpr
。
如果没有constexpr
,或const
代替constexpr
,代码的行为将完全相同。
但是,当您查看代码并看到constexpr int windowWidth;
时,您可以 100%
确定这是一个在运行时永远不会改变的不可变常量。
在my second tutorial video中,前三分钟内constexpr
上有一个附录,其中显示了constexpr
个函数以及更多constexpr
个示例/解释