【发布时间】:2015-12-07 10:26:45
【问题描述】:
这个问题是关于代码(在命名空间范围内):
std::vector<int> v1;
std::vector<int> v2(4);
在 C++14 (N4140) 的第 3.6.2 节中定义了一个术语常量初始化:
不断初始化:
- [省略 - 关于引用初始化]
- 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化完整表达式是该对象的常量初始化器;
- 如果具有静态或线程存储持续时间的对象未通过构造函数调用进行初始化,并且该对象是值初始化的,或者出现在其初始化程序中的每个完整表达式都是常量表达式。
此外,术语常量初始化器在前面定义过:
对象
o的常量初始化器是一个表达式,它是 常量表达式,除了它还可以为o及其子对象调用 constexpr 构造函数,即使这些对象是非文字类类型。
所以,看看std::vector<int> v2(4)。
此对象由构造函数调用初始化,因此它被第二个要点覆盖。初始化完整表达式为4。 4 是一个常量表达式,因此它是一个常量初始化器。所以满足了第二个要点,这应该是常量初始化的情况。
但是,我用一些编译器进行了测试,它们似乎都将v2 视为动态初始化。
对于v1 的情况,不清楚这是否算作“由构造函数调用初始化”;如果是这样,初始化完整表达式会是什么。
我的问题是:v1和v2是常量初始化,还是动态初始化;如果是后者,能否解释一下标准中的这些引用是如何解释的?
【问题讨论】:
-
@KerrekSB 我上面引用的文字来自 [basic.start.init]/2。也许它被认为是有缺陷的并在以后的草稿中被替换? N4296 仍然有相同的文本,这是我的最新草稿。
-
好吧,没关系。我认为措辞涵盖了构造函数必须是
constexpr的事实,但在以前的修订版中可能不清楚。见CWG 2026 可能吗? (编辑:)实际上,不,我认为更改不会影响您的观点。关于constexpr的措辞似乎没有改变。
标签: c++ initialization language-lawyer c++14