Что такое закрытый список фигурных скобок, если не список intializer_list?

Я задал здесь вопрос: Lifetime Расширение возврата initializer_list с использованием нефункционального кода:

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

Я полагал, что lambda пыталась вернуть intializer_list (это плохо, не делайте этого). Но я получил комментарий :

Это не initializer_list , это список инициализаторов. Две разные вещи.

Я просто подумал, что всякий раз, когда вы делаете фигурный скопированный список, вы создаете список intializer_list . Если это не то, что происходит, что такое список в фигурных скобках?

Здесь есть три различные, но связанные с ними понятия:

  1. braced-init-list : грамматическое правило, связанное с вложенными в фигурные скобки списками в определенных контекстах.

  2. Список инициализатора: имя инициализатора списка бит- инициализации, используемого в инициализации списка .

  3. std::initializer_list : class, который обертывает временный массив, который создается в некоторых контекстах, включая список бит-init-list .

Некоторые примеры:

 //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 auto e = { 4 }; //f used to be a std::initializer_list, but is now int after N3922 auto f { 4 }; 

Возможно, вам захочется прочитать N3922 , который изменил некоторые правила, связанные с auto и std::initializer_list .

Это бит-init-list . Список привязанных-init-list существовал до std::initializer_list и используется для инициализации агрегатов .

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

В приведенном выше примере был использован бит-init-list для инициализации массива, не создается std::initializer_list . С другой стороны, когда вы это делаете

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

foo не является агрегированным, поэтому бит-init-list используется для создания std::initializer_list который передается в конструктор foo который принимает std::initializer_list .

Замечание о скобках-init-list состоит в том, что у него нет типа, поэтому были разработаны специальные правила для использования с ним и auto . Он имеет следующее поведение (с момента принятия N3922 )

 auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list 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 auto x5{ 3 }; // decltype(x5) is int 

И вы можете получить дополнительную информацию об истории этого поведения и о том, почему он был изменен: Почему auto x {3} выводит initializer_list?

Я просто подумал, что всякий раз, когда вы делаете фигурный скопированный список, вы создаете список intializer_list .

Это неправильно.

Если это не то, что происходит, что такое список в фигурных скобках?

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

Часть {10, 20} не является параметром initializer_list . Это просто синтаксическая форма, чтобы использовать список объектов для создания другого объекта.

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

Еще раз, это синтаксическая форма для создания массива.

Имя для синтаксической формы – braced-init-list .

У вас есть две разные вещи при использовании {}

  1. A Тип std::initializer_list где значения могут быть неявно преобразованы в T
  2. Тип, который можно инициализировать со значениями списка.

Первый тип заставляет однородный список, а второй тип – нет. В следующем примере:

 struct S{ int a; string b }; void f1( S s ); void f2( int i ); void f3( std::initializer_list 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 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 
  • Инициализация свойства, точечная нотация
  • Swift: создание массива со значением по умолчанию для отдельных экземпляров объекта
  • инициализация массива c
  • Что происходит с объявленной, неинициализированной переменной в C? Имеет ли это значение?
  • Инициализация нескольких переменных для одного и того же значения в Java
  • Инициализация значений и типы не POD
  • C ++ 11 допускает инициализацию в classе нестатических и неконстантных элементов. Что изменилось?
  • Тип массива - правила для назначения / использования в качестве параметра функции
  • Weird undefined символы статических констант внутри struct / class
  • Можно ли инициализировать объединение в декларации?
  • Какова будет ценность неинициализированной переменной?
  • Interesting Posts

    Два интернет-соединения, одна локальная сеть – как поделиться?

    Компьютер не запускается, если питание не отключено в течение ~ 5 минут

    Что происходит, когда вы увеличиваете целое число за пределами его максимального значения?

    Как использовать несколько учетных записей SkyDrive на одном компьютере?

    Symfony 2: множественное и динамическое подключение к базе данных

    Android / Java – Опубликовать простой текст на стене Facebook?

    «Невозможно подключиться к виртуальной машине» для новой виртуальной машины Hyper-V

    Начиная с обновления до Windows 10 мой тачпад быстро переключается с включенного на отключенный

    Различия между / usr / bin / login и / usr / bin / bash

    Поиск контроля в элементе управления WPF

    Могу ли я использовать Unbuffered ECC-память с процессором без ECC?

    MVVM для winforms

    Какой метод вы используете для развертывания приложений ASP.Net в дикой природе?

    Авторизация ASP.NET MVC

    Как автокапитализировать первый символ в поле ввода в AngularJS?

    Давайте будем гением компьютера.