为什么要声明一个constexpr

时间:2013-12-01 06:23:46

标签: c++11 constexpr

在观看C++11 tutorial video linked on isocpp.org时,我注意到了一些事情:

constexpr int windowWidth{800}, windowHeight{600};

将这些int变量声明为constexpr而不只是const有什么意义?

2 个答案:

答案 0 :(得分:6)

好视频维托里奥!

以下是声明int constconstexpr之间差异的摘要:

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个示例/解释