12 c++ uniform-initialization c++11 list-initialization
C++ 11引入了{}式初始化.但这两种形式是什么
T x {...};
T x = {...};
Run Code Online (Sandbox Code Playgroud)
相同?
jua*_*nza 13
它们并不完全相同.也许这可以通过反例来说明:
struct Foo
{
explicit Foo(std::initializer_list<int>) {}
};
int main()
{
Foo f0{1, 2, 3}; // OK
Foo f1 = {1, 2, 3}; // ERROR
}
Run Code Online (Sandbox Code Playgroud)
因此,第二个变体要求类型可以从初始化列表中隐式构造,而第一个版本则不需要.请注意,这同样适用于表单的构造函数Foo(int, int, int).我initializer_list<int>任意选择了这个例子.
这会影响按照"无处不在"的原则编写的某些类型(即人们explicit在C++ 03代码中标记了多参数构造函数,即使它在该标准中没有意义.)
除了在juanchopanza的答案中解释的差异之外,还有另一个区别,即直接列表初始化和复制列表初始化之间的一个重大变化,它涉及到braced-init-list的auto类型推断.虽然它没有作为C++ 14(最后一个Q&A项目)的一部分添加,但是已经确定了问题,并且由委员会实施时将由它决定.
例如,
auto foo = {42}; // deduces foo as an initializer_list<int>
auto foo{42}; // deduces foo as an int
Run Code Online (Sandbox Code Playgroud)
所以直接列表初始化永远不会initializer_list从参数中推断出一个.因此,以下将是不正确的.
auto foo{1,2}; // cannot have multiple initializers for
// direct-list-initialization when deducing type
Run Code Online (Sandbox Code Playgroud)
但这没关系:
auto foo = {1,2}; // copy-list-initialization still deduces initializer_list<int>
Run Code Online (Sandbox Code Playgroud)
这同样适用于lambda表达式中的广义捕获.引用N3912
[x{5}](){}; // x is int
[x{1,2}](){}; // ill-formed, no multiple initializers with direct-init
[x = {5}](){}; // ok, x is an initializer_list<int> with one element
[x = {1,2}](){}; // ok, x is an initializer_list<int> with two elements
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
749 次 |
| 最近记录: |