Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这些是矢量定义吗;常量初始化";?_C++_Initialization_Language Lawyer_C++14 - Fatal编程技术网

C++ 这些是矢量定义吗;常量初始化";?

C++ 这些是矢量定义吗;常量初始化";?,c++,initialization,language-lawyer,c++14,C++,Initialization,Language Lawyer,C++14,此问题与代码有关(在命名空间范围内): std::vector v1; std::载体v2(4); 在C++14(N4140)的第3.6.2节中,定义了一个术语常量初始化: 执行常量初始化: [省略-关于引用初始化] 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化完整表达式是该对象的常量初始值设定项 如果构造函数调用未初始化具有静态或线程存储持续时间的对象,并且如果该对象已初始化值,或者其初始值设定项中出现的每个完整表达式都是常量表达式 此外,术语常量初始值设定项的定

此问题与代码有关(在命名空间范围内):

std::vector v1;
std::载体v2(4);
在C++14(N4140)的第3.6.2节中,定义了一个术语常量初始化:

执行常量初始化:

  • [省略-关于引用初始化]
  • 如果具有静态或线程存储持续时间的对象由构造函数调用初始化,并且初始化完整表达式是该对象的常量初始值设定项
  • 如果构造函数调用未初始化具有静态或线程存储持续时间的对象,并且如果该对象已初始化值,或者其初始值设定项中出现的每个完整表达式都是常量表达式
此外,术语常量初始值设定项的定义就在前面:

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

那么,看看std::vector v2(4)

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

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

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


我的问题是:
v1
v2
是恒定初始化还是动态初始化;如果是后者,是否可以解释标准中的这些引用是如何解释的?

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

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

然后,根据8.5/17,直接初始化(同时使用
v1
v2
)涉及构造函数调用


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

@KerrekSB我上面引用的文本来自[basic.start.init]/2.也许它被认为是有缺陷的,并在以后的草稿中被替换掉了?N4296仍然有相同的文本,这是我拥有的最新草稿。好吧,没关系。我认为措辞涵盖了构造函数必须是
constexpr
,但在以前的修订中可能不清楚。请参阅maybe?(编辑:)事实上,不,我不认为这个改变会影响你的观点。关于
constexpr
的措辞似乎没有改变。我明白了。所以
s1(1);
是一个完整的表达,尽管它不是一个expression@M.M差不多。虽然从技术上讲,只有对
S::S(int)
的调用才是完整的表达式,而不是声明本身。
std::vector<int> v1;
std::vector<int> v2(4);
S s1(1); // full-expression is call of S::S(int)