这两种在C++ 11中初始化变量的方法之间有什么细微的差别吗?
vector<double> v { 0.0, 1.1, 2.2, 3.3 };
vector<double> v = { 0.0, 1.1, 2.2, 3.3 };
后者可以用于与第一个相同的所有情况吗?
Stroustrup在TCPL4ED中声称第一种方式是唯一可以在每个上下文中使用的方法,因此推荐它.后来,他似乎暗示第二个只是写第一个的另一种方式.
vector<double> v { 0.0, 1.1, 2.2, 3.3 };
Run Code Online (Sandbox Code Playgroud)
是直接列表初始化.这意味着它是使用构造函数初始化列表初始化的.
构造函数:
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)
vector<double> v = { 0.0, 1.1, 2.2, 3.3 };
Run Code Online (Sandbox Code Playgroud)
是复制列表初始化.
标准很清楚:
8.5.4列表初始化[dcl.init.list]
列表初始化是从braced-init-list初始化对象或引用.这样的初始化程序称为初始化程序列表,列表的逗号分隔的初始化程序子句称为初始化程序列表的元素.初始化列表可以为空.列表初始化可以在直接初始化或copyinitialization上下文中进行; 直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化.[注意:可以使用列表初始化:
- 作为变量定义中的初始化器
[...]
示例:
Run Code Online (Sandbox Code Playgroud)std::complex<double> z{1,2}; [...] std::map<std::string,int> anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} };
对于两者之间的差异,我们应该进一步:
13.3.1.7按列表初始化初始化[over.match.list]
- 对于直接列表初始化,候选函数是类T的所有构造函数.
- 对于复制列表初始化,候选函数是T的所有构造函数. 但是,如果
explicit选择构造函数,则初始化是错误的.[注意:此限制仅适用于此初始化是重载解析的最终结果的一部分 - 结束注释]
统一初始化的目的是(部分)消除这两种结构之间的差异.确保它们具有相同的功能.
可悲的是,他们失败了.有只有一个差异直接列表初始化之间(即:T t{...})和复制列表初始化(即:T t = {...}).您不需要复制/移动构造函数进行复制列表初始化(尽管名称); 第8.5.4节没有将其列为要求.没有一个临时建造的概念可能会被遗弃.他们有相同的行为,除了:
如果选择explicit构造函数,则复制列表初始化将失败.这是唯一的区别.
很难从规范中引用一个引用,因为只有3个提到复制列表初始化是什么.一个是在8.5.4中,它定义了复制列表初始化是列表初始化的一种形式,另一个说明返回一个braced-init-list使用复制列表初始化.13.3.1.7中的最后一个,它说明了上述异常:
在copy-list-initialization中,如果
explicit选择了构造函数,则初始化是错误的.
这是唯一的区别.
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |