Почему синтаксис двойных фигурных скобок не предпочтителен для конструкторов, принимающих std :: initializer_list

Равномерная инициализация является важной и полезной функцией C ++ 11. Тем не менее, вы не можете просто использовать{} с тех пор

std::vector<int> a(10, 0);    // 10 elements of value zero
std::vector<int> b({10, 0});  // 2 elements of value 10 and 0 respectively
std::vector<int> c{10, 0};    // 2 elements of value 10 and 0 respectively
std::vector<int> d = {10, 0}; // 2 elements of value 10 and 0 respectively

auto e(0);    // deduced type is int
auto f = 0;   // deduced type is int
auto g{0};    // deduced type is std::initializer_list<int>
auto h = {0}; // deduced type is std::initializer_list<int>

Отмечая чтоагрегатная инициализация например,std::arrays требует использования{{}}мне кажется, что вся проблема скакой векторный конструктор будет выбран можно было бы избежать, потребовав{{}} вызывать конструкторов, принимающихstd::initializer_list:

std::vector<int> i{10, 0};    // 10 elements of value zero
std::vector<int> j{{10, 0}};  // 2 elements of value 10 and 0 respectively
std::vector<int> k = {10, 0}; // 2 elements of value 10 and 0 respectively

auto l{0};    // deduced type is int
auto m{{0}};  // deduced type is std::initializer_list<int>
auto n = {0}; // deduced type is std::initializer_list<int>

Я уверен, что это обсуждалось, так каковы были причины против этого? Цитата / ссылка из стандартного предложения предпочтительнее в качестве ответа.

Обновить. - Есть смысл вN2532 что говорится:

(3) Вероятные неприятные случаи неоднозначности происходят только для коротких списков инициализаторов [...]

(5) Почему языковые правила должны заставлять программистов, которые хотят, чтобы краткость и контроль неоднозначности (по вполне веским причинам) писали больше, чтобы угодить программистам, которые предпочитают (по совершенно веским причинам) быть более явными - и может быть?

[...]

Предположим, что программист ожидает вызова функции f (X). Как f (Y) может «перехватить» звонок?

(4) Предположим, что X не имеет конструктора списка инициализаторов, а Y имеет. В этом случае приоритет, отданный конструкторам списка инициализаторов, отдает предпочтение угонщику (помните, мы предполагали, что программист каким-то образом ожидал вызова функции f (X)). Это аналогично тому, что кто-то ожидает, что f (y) вызовет f (X), используя пользовательское преобразование, и кто-то придет с f (Y), который точно совпадает.Я думаю, было бы справедливо ожидать, что кто-то, кто использует {…}, вспомнит о возможности конструкторов списков инициализаторов. [Акцент мой]

Я думаю, ключ кроется вможет бытьЭто означает, что вам не нужно использовать одинаковую инициализацию. С помощью{} правильно трудно, так как:

Вы должны не только проверить конструктор, который вы хотите вызвать, но и длялюбой конструктор принимаетinitializer_list это может победить (и, вероятно, будет) над этим;

если вы пишете код, используя{} и кто-то в будущем добавляетstd::initializer_list конструктор ваш код может сломаться и сделать этомолча.

Даже если у вас есть классA с конструкторамиA(int, bool) а такжеA(std::initializer_list<double>), последний будет выбран над первым дляA a{0, false}; (что IMO сумасшедший), так что я нахожу этодействительно трудно использовать равномерную инициализацию для классов, которые имеют илиможет быть есть (требуется сверхдержава хрустального шара)initializer_list Конструкторы.

Тот факт, что ваш код может молча взломать меня очень беспокоит.

Ответы на вопрос(2)

Ваш ответ на вопрос