什么是大括号括起来的列表。如果不是一个intializer_list?什么是大括号括起来的列表。如果

2019-05-11 21:50发布

我在这里问一个问题: 一个initializer_list回报寿命延长涉及非功能性的代码:

const auto foo = [](const auto& a, const auto& b, const auto& c) { return {a, b, c}; };

我相信拉姆达试图返回intializer_list但我得到了(这是很糟糕,不这样做。) 评论 :

这不是一个initializer_list ,这是一个初始化列表。 两个不同的东西。

我只是觉得,你做了一个大括号列表中的任何时候你创建一个intializer_list 。 如果不是发生了什么,什么是大括号的列表?

Answer 1:

有三种不同的,但相关的概念,在这里:

  1. 支撑-初始化列表 :在某些情况下花括号封闭列表相关的语法规则。

  2. 初始化列表:在列表初始化中使用的支撑,初始化列表初始化的名称。

  3. std::initializer_list :A类包装,其在涉及支撑-INIT-表 S一些上下文中创建的临时数组。

一些例子:

//a braced-init-list and initializer list, 
//but doesn't create a std::initializer_list
int a {4}; 

//a braced-init-list and initializer list,
//creates a std::initializer_list
std::vector b {1, 2, 3};

//a braced-init-list and initializer list,
//does not create a std::initializer_list (aggregate initialization)
int c[] = {1, 2, 3};

//d is a std::initializer_list created from an initializer list
std::initializer_list d {1, 2, 3};

//e is std::initializer_list<int>
auto e = { 4 };

//f used to be a std::initializer_list<int>, but is now int after N3922
auto f { 4 };

你可能想读N3922 ,它改变了一些涉及规则autostd::initializer_list



Answer 2:

这是一个支撑,初始化列表 。 一个支撑-初始化列表之前就已经存在std::initializer_list ,用来初始化一个集合 。

int arr[] = {1,2,3,4,5};

上述中使用的支撑-INIT列表初始化数组,没有std::initializer_list被创建。 在当你做另一方面

std::vector<int> foo = {1,2,3,4,5};

foo是不是总这样的支撑,初始化列表被用于创建std::initializer_list这是在翻传递给的构造函数foo一个接受std::initializer_list

需要注意一个支撑-INIT-list中的事情是没有类型如此特殊规则与它和使用而开发的auto 。 它具有以下行为(通过自N3922 )

auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
auto x3{ 1, 2 }; // error: not a single element
auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
auto x5{ 3 }; // decltype(x5) is int

你可以得到的这种行为历史的更多信息,以及为什么它在改变: 为什么汽车X {3}演绎一个initializer_list?



Answer 3:

我只是觉得,你做了一个大括号列表中的任何时候你创建一个intializer_list

这是不正确的。

如果不是发生了什么,什么是大括号的列表?

struct Foo {int a; int b;};
Foo f = {10, 20};

{10, 20}的部分不是一个initializer_list 。 这只是一个语法形式使用对象的列表创建另一个对象。

int a[] = {10, 20, 30};

再次,这是一个语法形式来创建阵列。

对于语法形式的名称braced-init-list



Answer 4:

你有两个不同的事情时,使用{}

  1. A型std::initializer_list<T>其中值可以隐式转换到T
  2. 可以用列表的值来初始化A型。

第一种强制均匀名单,而第二类则没有。 在下面的例子:

struct S{ 
    int a; 
    string b 
};

void f1( S s );
void f2( int i );
void f3( std::initializer_list<int> l );

f1( {1, "zhen"} ); // construct a temporal S
f2( {1} );         // construct a temporal int
f3( {1,2,3} );     // construct a temporal list of ints

的函数f1和f2使用第一类型和f3使用第二类型。 你应该知道,如果有歧义,在std :: initializer_list是首选。 例如:

void f( S s );
void f( int i );
void f( std::initializer_list<int> l );

f( {1, "zhen"} ); // calls with struct S
f( {1} );         // calls with int list with one element
f( {1,2,3} );     // calls with int list with three elements


文章来源: What Is a Curly-Brace Enclosed List If Not an intializer_list?