Читая о другой теме, я столкнулся со странным поведением, по крайней мере, со мной.Вся эта мысль возникла из особых взаимодействий между auto
и фигурными скобками.Если вы напишите что-то вроде:
auto A = { 1, 2, 3 }
, компилятор выведет A
в std::initializer_list
.Странно то, что подобное правило применяется не только к auto
, где для этого могут быть особые причины, но и к другим вещам.Если вы напишите следующее:
template<typename T>
void f(std::vector<T> Vector)
{
// do something
}
, вы, конечно, не сможете так его назвать:
f({ 1, 2, 3});
, даже если std::vector
можно инициализировать в скобках.Однако, если вы замените std::vector
на std::initializer_list
, вызов сработает, и компилятор правильно выведет int
как тип T
.Однако более интересным является то, что в первом случае вам нужно #include <vector>
, во втором - #include <initializer_list>
.Это заставило меня задуматься, и после теста я понял, что std::initializer_list
не нужен собственный заголовок, так что это в некоторой степени часть "базовых" функций.
Более того, чтобы все имело смысл,std::initializer_list
должно относиться к стандартным объектам более или менее так же, как лямбды к вызываемым объектам (в самом строгом смысле, это объект с operator()
).Другими словами, безымянные фигурные скобки по умолчанию должны иметь значение std::initializer_list
, так же как лямбды (в основном) являются неназванными вызываемыми объектами.
Правильно ли это рассуждение?Более того, можно ли изменить это поведение и, если да, то как?
ОБНОВЛЕНИЕ: было обнаружено, что заголовок для initializer_list
транзитивно включен из iostream
(действительно странно).Однако остается вопрос: почему звонок работает на std::initializer_list
, а не на std::vector
?