gpt4 book ai didi

c++ - "surprising"常量初始化因为定义顺序

转载 作者:IT老高 更新时间:2023-10-28 23:01:36 28 4
gpt4 key购买 nike

阅读 slides about constexpr 时介绍是关于“令人惊讶的 consts 动态初始化”。例子是

struct S {
static const int c;
};
const int d = 10 * S::c;
const int S::c = 5;

唉,音轨不见了,笔记也不见了,所以我只能猜测这里的意思。

d 对吗?被“令人惊讶地”动态初始化,因为 S::c定义在之前 d ? S::c声明d 之前可能还不够,编译器需要完整的定义,对吧?

也就是说,我怀疑在以下示例中 d 静态初始化吗?

struct S {
static const int c;
};
const int S::c = 5;
const int d = 10 * S::c; // now _after_ defn of S::c

为了获得蛋糕,在 C++11 中,必须是 constexpr 用于完全静态初始化? S::c , d还是两者都有?

最佳答案

在第一个例子中,d 没有被一个常量表达式初始化,因为 S::c 不是

a non-volatile const object with a preceding initialization, initialized with a constant expression

(参见 C++11 [expr.const]p2,关于左值到右值转换的项目符号),因为 S::c 的初始化不会先于 的初始化d。因此 S::c 会使用静态初始化(因为它是由常量表达式初始化的),而 d 可以使用动态初始化。

由于静态初始化在动态初始化之前,d 将被其动态初始化程序初始化为 50。允许编译器将 d 的动态初始化转换为静态初始化,但如果这样做,它必须生成 d 的值,如果每个变量可以具有使用了动态初始化,事实上,使用了动态初始化。在这种情况下,无论哪种方式,d 都会被初始化为 50。有关这方面的更多信息,请参阅 C++11 [basic.start.init]p2。

没有办法在第一个例子中添加constexpr来保证d使用静态初始化;为此,您必须重新排序初始化。但是,添加 constexpr 将为第一个示例生成诊断信息,这至少可以让您确保使用动态初始化(您得到静态初始化或编译错误)。

您可以更新第二种情况以确保使用静态初始化如下:

struct S {
static const int c; // do not use constexpr here
};
constexpr int S::c = 5;
constexpr int d = 10 * S::c;

在不是定义的变量声明上使用 constexpr 或在不包含初始化程序的变量声明上使用它是不正确的,所以 const code>,而不是 constexpr 必须在 struct S 的定义中使用。此规则有一个异常(exception),即在定义文字、非整数类型的 static constexpr 数据成员时,使用类中指定的初始化程序:

struct T { int n; };
struct U {
static constexpr T t = { 4 };
};
constexpr T U::t;

在这种情况下,必须在类的定义中使用 constexpr,以允许提供初始化程序,并且必须在定义中使用 constexpr静态数据成员,以便允许在常量表达式中使用它。

关于c++ - "surprising"常量初始化因为定义顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7625952/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com