Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.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++ 什么';“objectobj(args…”和“objectobj{args…}”之间的区别是什么?_C++_Oop_C++11_Constructor_Uniform Initialization - Fatal编程技术网

C++ 什么';“objectobj(args…”和“objectobj{args…}”之间的区别是什么?

C++ 什么';“objectobj(args…”和“objectobj{args…}”之间的区别是什么?,c++,oop,c++11,constructor,uniform-initialization,C++,Oop,C++11,Constructor,Uniform Initialization,Scott Meyers撰写的新书草稿指出: 创建对象时区分()和{} objectobj(args…和objectobj{args…}之间有什么区别?为什么斯科特这么说 更新: 这个问题问如何,这个问题问为什么 更新2: 我发现以下链接很有帮助,完全回答了这个问题: objectobj(args…)和objectobj{args…}之间有什么区别?为什么斯科特这么说 不同之处在于,在前一种情况下,参数的求值顺序是不排序的(即未指定),但在后一种情况下,求值顺序是从左到右的(即它们出现的顺序)

Scott Meyers撰写的新书草稿指出:

创建对象时区分()和{}

objectobj(args…
objectobj{args…}
之间有什么区别?为什么斯科特这么说

更新:

这个问题问如何,这个问题问为什么

更新2:

我发现以下链接很有帮助,完全回答了这个问题:

objectobj(args…)和objectobj{args…}之间有什么区别?为什么斯科特这么说

不同之处在于,在前一种情况下,参数的求值顺序是不排序的(即未指定),但在后一种情况下,求值顺序是从左到右的(即它们出现的顺序)

以下来自$5.2.2/8[expr.call](n3690)的文本涉及
对象(args…
表单:

后缀表达式和参数的求值都是相对于彼此不排序的。在输入函数之前,参数计算的所有副作用都按顺序排列(见1.9)

$8.5.4/4[dcl.init.list](n3690)中的文本处理
Object{args…}
表单:

在带括号的init列表的初始值设定项列表中 初始值设定项子句,包括由包扩展产生的任何 (14.5.3),按照其出现的顺序进行评估。就是, 与给定值相关的每个值计算和副作用 初始值设定项子句在每次值计算和 与本协议中任何初始值设定项条款相关的副作用 初始值设定项列表的逗号分隔列表。[注意:此 无论函数的语义如何,求值顺序都保持不变 初始化;例如,当 初始值设定项列表被解释为构造函数调用的参数, 即使通常在 调用的参数。-结束注释]

也就是说:

 int f() { static int i = 10; return ++i; }  //increment the static int!

 Object obj(f(), f()); //is it obj(11,12) or obj(12,11)? Unspecified. 

 Object obj{f(), f()}; //it is obj(11,12). Guaranteed.
请注意。我不确定它在当前版本中是否已修复


希望有帮助

objectobj(args…和
Object{args…}
的行为取决于
Object
中定义的构造函数

以以下为例:

#include <iostream>
#include <initializer_list>

struct A
{
   A(int a, int b) {std::cout << "Came to A::A()\n";}
};

struct B
{
   B(int a, int b) {std::cout << "Came to B::B(int, int)\n";}
   B(std::initializer_list<int> in) {std::cout << "Came to B::B(std::initializer_list<int>)\n";}
};

int main()
{
   A a1(10, 20); // Resolves to A(int, int)
   A a2{10, 20}; // Resolves to A(int, int)
   A a3{30};     // Does not resolve to anything. It's a compiler error.

   B b1(10, 20); // Resolves to B(int, int)
   B b2{10, 20}; // Resolves to B(std::initializer_list<int> )
   B b3{30};     // Resolves to B(std::initializer_list<int> )

}
#包括
#包括
结构A
{
A(inta,intb){std::cout
objectobj(args…
objectobj{args…}
之间有什么区别

第一个是直接初始化,第二个是直接列表初始化。这在两个不同的部分中提到:

§8.5/16[初始dcl]

表单中发生的初始化

 T x(a);
 T x{a};
new
表达式(5.3.4)、
static_-cast
表达式(5.2.9)、函数表示法类型转换(5.2.3)以及基和成员初始值设定项(12.6.2)中,称为直接初始化

和§8.5.4/1【dcl初始列表】

列表初始化是从带括号的初始化列表初始化对象或引用。此类初始化器称为初始化器列表,列表中以逗号分隔的初始化器子句称为初始化器列表的元素。初始化器列表可能为空。列表初始化可在直接初始化或copy初始化上下文;直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化


两者之间有一些区别:

  • 如果正在构造的类型具有采用
    初始值设定项列表
    参数的构造函数,则直接列表初始化将始终支持该构造函数。只有当
    初始值设定项列表
    构造函数不可行时,才会考虑其他构造函数。§13.3.1.7/1[超过.match.list]

  • 直接列表初始化不允许缩小参数列表内的转换范围。§8.5.4/3[dcl.init.list]

  • 如果要初始化的类型是聚合,则直接列表初始化将执行聚合初始化。§8.5.4/3[dcl.init.list]

  • 括号内初始列表元素的计算顺序为从左到右。§8.5.4/4[dcl.初始列表]

  • 通过使用直接列表初始化,可以避免最麻烦的解析

objectobj(args…)和objectobj{args…}之间有什么区别

{args…}与其他合法候选构造函数相比,更喜欢具有初始值设定项\u列表的构造函数

std::vector<int> v(10); // vector of size 10
std::vector<int> v{10}; // vector initialized with a single element, (int) 10
std::vector v(10);//大小为10的向量
std::vector v{10};//用单个元素初始化的向量,(int)10
另一方面,您放弃隐式缩小

std::vector<int> v(10.5); // vector of size 10
std::vector<int> v{10.5}; // illegal - no compile
std::vector<float> v{10.5}; // vector initialized with a single element, (float) 10.5
std::vector v(10.5);//大小为10的向量
std::vector v{10.5};//非法-无编译
std::vector v{10.5};//用单个元素初始化的向量,(float)10.5

@MattMcNabb的可能重复,这个问题问如何,这个问题问为什么。这个问题不问“为什么”,另一个问题涉及统一初始化的作用。一个是直接初始化,另一个是列表初始化。标准中有大量关于这两个方面的具体信息。@MattMcNabb,我引用Scott的说法,想知道他为什么这么说。
std::vector<int> v(10.5); // vector of size 10
std::vector<int> v{10.5}; // illegal - no compile
std::vector<float> v{10.5}; // vector initialized with a single element, (float) 10.5