Что может пойти не так, если инициализация копирования списка позволила явные конструкторы?

В стандарте C ++, §13.3.1.7 [over.match.list], указано следующее:

В инициализации копирования списка, еслиexplicit конструктор выбран, инициализация некорректна.

Это причина, почему мы не можем сделать, например, что-то вроде этого:

struct foo {
    // explicit because it can be called with one argument
    explicit foo(std::string s, int x = 0);
private:
    // ...
};

void f(foo x);

f({ "answer", 42 });

(Обратите внимание, что здесь происходитне конверсияи это не будет единица, даже если конструктор был «неявным». Это инициализацияfoo объект, используя его конструктор напрямую. Кромеstd::stringздесь нет конвертации.)

Мне кажется, это прекрасно. Нет никакого способа, которым неявное преобразование укусит меня.

Если{ "answer", 42 } может инициализировать что-то еще, компилятор не предаст меня и не сделает ничего плохого:

struct bar {
    // explicit because it can be called with one argument
    explicit bar(std::string s, int x = 0);
private:
    // ...
};

void f(foo x);
void f(bar x);

f({ "answer", 42 }); // error: ambiguous call

Нет проблем: вызов неоднозначный, код не будет компилироваться, и мне придется явно определить перегрузку.

f(bar { "answer", 42 }); // ok

Так как запрет явно указан, у меня такое ощущение, что я что-то здесь упускаю. Насколько я вижу, явные конструкторы выбора инициализации списка не кажутся мне проблемой: используя синтаксис инициализации списка, программист уже выражает желание выполнить какое-то «преобразование».

Что может пойти не так? Что мне не хватает?

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

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