Инициализация скаляров с помощью фигурных скобок

В C и С++ можно инициализировать массивы и структуры с помощью фигурных скобок:

int a[] = {2, 3, 5, 7};
entry e = {"answer", 42};

Однако, в разговоре с 2007 года, Бьярне упоминает, что этот синтаксис также работает для скаляров. Я попробовал:

int i = {7};

И это действительно работает! В чем заключается обоснование возможности инициализации скаляров с помощью фигурных скобок?

Примечание. Я специально не говорю о единообразной инициализации С++ 11. Это хороший старый C89 и С++ 98.

Ответ 1

В чем заключается обоснование возможности инициализации скаляров с помощью фигурных скобок?

int - POD. Таким образом, инициализация скобки допускается в случае int (и для всех типов встроенных), так как синтаксис инициализации соответствует другим POD.

Кроме того, я думаю, что любое обоснование синтаксиса синтаксиса С++ 11 равно, также (частично) применимо к этому синтаксису, разрешенному С++ 03. Просто С++ 03 не расширил его, включив в него типы не-типа, такие как стандартные контейнеры.

Я вижу одно место, где эта инициализация полезна в С++ 03.

template<typename T>
void f()
{
    T  obj = { size() } ; //T is POD: built-in type or pod-struct
    //code
}

Теперь это можно создать с помощью struct, который начинается с подходящего элемента, а также любого арифметического типа:

struct header
{ 
    size_t size; //it is the first member
    //...
};

f<header>(); //body becomes : header obj = { size(); }; which is fine
f<size_t>(); //body becomes : size_t obj = { size(); }; which is fine

Также обратите внимание, что POD, будь то структурные или встроенные типы, также можно инициализировать равномерно:

header h = header(); //value-initialized
int    i = int();    //value-initialized

Поэтому я считаю, что одна из причин - последовательность.

Ответ 2

Обоснование не упоминается, но из 2005 С++ Стандартный проект, 8.5 Инициализаторы [dcl.init], раздел 14

Если T - скалярный тип, то объявление вида T x = { a }; эквивалентно T x = a;

Обратите внимание, что в стандарте С++ 98 допускаются только инициализаторы скобок для инициализации копирования T x = { a }, а не для прямой инициализации T x { a }, для которых работает только T x(a).

UPDATE: см. также question

Ответ 3

С++, вероятно, унаследовал это от C. В C основной причиной является наличие уникального синтаксиса инициализатора, в частности, для инициализатора по умолчанию. В C инициализатор по умолчанию имеет значение {0}.