这些向量定义"constant initialization"吗?

Are these vector definitions "constant initialization"?

本文关键字:initialization constant 向量 定义      更新时间:2023-10-16

这个问题是关于代码(在命名空间范围内):

std::vector<int> v1;
std::vector<int> v2(4);

在C++14(N4140)的第3.6.2节中,定义了一个术语常量初始化

执行恒定初始化:

  • [省略-关于引用初始化]
  • 如果具有静态或线程存储持续时间的对象是由构造函数调用初始化的,并且如果初始化完整表达式是该对象的常量初始化器
  • 如果具有静态或线程存储持续时间的对象未由构造函数调用初始化,并且该对象是值初始化的,或者其初始化器中出现的每个完整表达式都是常量表达式

此外,术语常量初始值设定项是在前面定义的:

对象o常量初始值设定项是一个表达式常量表达式,只是它也可以调用o及其子对象的constexpr构造函数,即使这些对象是非文字类类型的。

所以,看看std::vector<int> v2(4)

这个对象是由构造函数调用初始化的,所以它被第二个要点覆盖。初始化完整表达式为44是一个常量表达式,因此它是一个常量初始值设定项。因此,满足第二个要点,这应该是常量初始化的情况。

然而,我用一些编译器进行了测试,它们似乎都将v2视为动态初始化

对于v1的情况,尚不清楚这是否算作"由构造函数调用初始化";如果是,初始化完整表达式将是什么。

我的问题是:v1v2是常量初始化,还是动态初始化

根据1.9/10,初始化的完整表达式包括对构造函数的调用:

完整表达式是一个不是另一个表达式的子表达式的表达式。。。如果一个语言构造被定义为生成函数的隐式调用,则该语言的使用构造被认为是本定义中的一种表达方式。。。为满足语言要求而应用于表达式结果的转换表达出现在其中的构建体也被认为是完整表达的一部分
[示例:

S s1(1); // full-expression is call of S::S(int)

然后,根据8.5/17,直接初始化(v1v2都使用)涉及构造函数调用。

因此,构造函数调用是您引用的第二个项目符号的"初始化完整表达式"的一部分。因此,构造函数调用,而不仅仅是4,是完整的表达式。这反过来意味着这样一个构造函数必须是constexpr才能符合常量初始值设定项的条件(如您所引用的,根据其定义)。由于std::vector的默认构造函数和size_t构造函数都不是constexpr,因此初始化不是恒定的。

相关文章: