Ответ 1
Есть ли какой-нибудь случай, когда это абсолютно необходимо?
Нет. Но вещи не добавляются, потому что они "абсолютно понадобятся". Они добавляются, потому что они полезны.
И неявно конвертируемый из одного из его типов компонентов очень полезен для variant
. Да, это создает двусмысленность в некоторых случаях. Но эта неоднозначность обычно связана с дефектами в дизайне типов (например, строковые литералы, предпочитающие преобразовывать в bool
по пользовательским преобразованиям).
Если существует двусмысленный случай, тогда вам просто нужно быть явным. Как использование "abc"s
литералов UDL, а не голых строковых литералов (еще одна причина для этого). Но нет причин заставить всех быть явным, когда вы имеете дело с хорошо продуманными типами.
Не будет (5) и (7) служить целям, для которых (6) и (8) предназначены для?
Не разумным способом.
В каждом случае в стандарте, когда функция принимает переменные аргументы, которые будут переданы конструктору, они будут использовать синтаксис конструктора, а не синтаксис {}
для этого объекта. Поэтому, если у вас есть это:
using type = vector<int>;
variant<type> t(in_place<type>, 6);
Вы получите звонок vector<int>(6)
. Обратите внимание, что это отличается от vector<int>{6}
. То есть вы не получаете конструкторы списка инициализаторов, если вы фактически не передаете список инициализаторов.
Теперь вы можете сделать:
variant<type> t(in_place<type>, initializer_list<int>{6});
Но это слишком многословно. Напротив:
variant<type> t(in_place<type>, {6});
Это гораздо менее многословно. Компилятор может вывести тип списка инициализаторов. В то время как вывод типа аргумента шаблона не получается, если вы попытаетесь вывести braced-init-list
как произвольное T
.
Среди других способов вычитание шаблона отличается от вычета с помощью auto
, потому что оно не выводит выражения initializer_list
из braced-init-list
. Например
template <typename Type>
void func(const Type&);
не выводит Type
как std::initializer_list
для следующего вызова
func({1, 2, 3, 4, 5});
для получения дополнительной информации об этом см. Универсальные ссылки и std:: initializer_list.