这个问题是关于代码(在命名空间范围内):
std::vector<int> v1;
std::vector<int> v2(4);
在C ++ 14(N4140)的3.6.2节中,定义了一个术语常量初始化:
执行常量初始化:
- [省略 - 关于参考初始化]
- 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化full-expression是对象的常量初始化器;
- 如果具有静态或线程存储持续时间的对象未通过构造函数调用初始化,并且该对象是值初始化的,或者其初始化程序中出现的每个完整表达式都是常量表达式。
此外,术语常量初始值设定项在前面定义:
对象
o
的常量初始值设定项是一个表达式 常量表达式,除了它还可以为o
及其子对象调用constexpr构造函数,即使这些对象是非文字类类型。
所以,看std::vector<int> v2(4)
。
此对象由构造函数调用初始化,因此它被第二个项目符号点覆盖。初始化全表达式为4
。 4
是一个常量表达式,因此它是常量初始值设定项。因此第二个要点得到满足,这应该是常量初始化的情况。
但是,我测试了一些编译器,所有这些编译器似乎都将v2
视为动态初始化。
对于v1
情况,不清楚这是否算作&#34;由构造函数调用初始化&#34 ;;如果是这样,初始化完整表达式将是什么。
我的问题是:v1
和v2
常规初始化,还是动态初始化;如果是后者,是否可以解释这些标准中的引用是如何解释的?
答案 0 :(得分:7)
根据1.9 / 10,初始化的完整表达包括对构造函数的调用:
full-expression 是一个表达式,它不是另一个表达式的子表达式。 ...如果定义语言构造以产生函数的隐式调用,则使用该语言 构造被认为是用于该定义目的的表达。 ...转换应用于表达式的结果,以满足语言的要求 表达式出现的构造也被认为是完整表达的一部分 [示例:
...S s1(1); // full-expression is call of S::S(int)
然后,根据8.5 / 17,直接初始化(v1
和v2
都使用)涉及构造函数调用。
因此,构造函数调用是您引用的第2个项目符号点的“初始化完整表达式”的一部分。所以构造函数调用,而不仅仅是4
,是完整表达式。这反过来意味着这样的构造函数必须constexpr
才能成为常量初始化程序(根据您的定义,如您所引用的那样)。由于size_t
的默认构造函数和std::vector
构造函数都不是constexpr
,因此初始化不是常量。