Ответ 1
Это своего рода контракт между программистом и компилятором. Программист говорит {1,2,3,4}
, и компилятор создает из него объект типа initializer_list<int>
, содержащий ту же последовательность элементов в нем. Этот контракт является требованием, заданным спецификацией языка в реализации компилятора.
Это означает, что программист не создает вручную такой объект, но это компилятор, который создает объект, и передает этот объект функции, который принимает initializer_list<int>
как аргумент.
Реализация std::vector
использует этот контракт и поэтому определяет конструктор, который принимает initializer_list<T>
в качестве аргумента, так что он может инициализировать себя элементами в списке инициализаторов.
Теперь предположим какое-то время, что std::vector
не имеет конструктора, который принимает std::initializer_list<T>
в качестве аргумента, тогда вы получите следующее:
void f(std::initializer_list<int> const &items);
void g(std::vector<int> const &items);
f({1,2,3,4}); //okay
g({1,2,3,4}); //error (as per the assumption)
В соответствии с предположением, поскольку std::vector
не имеет конструктора, который принимает std::initializer_list<T>
как аргумент, из которого следует, что вы не можете передать {1,2,3,4}
в качестве аргумента в g()
, как показано выше, поскольку компилятор не может создать экземпляр из std::vector
из выражения {1,2,3,4}
напрямую. Это связано с тем, что такой контракт никогда не заключен между программистом и компилятором и не навязывается языком. Через std::initializer_list
std::vector
может создать себя из выражения {1,2,3,4}
.
Теперь вы поймете, что std::initializer_list
можно использовать везде, где вам нужно выражение формы {value1, value2, ...., valueN}
. Именно поэтому другие контейнеры из библиотеки Standard также определяют конструктор, который принимает std::initializer_list
как аргумент. Таким образом, никакой контейнер не зависит от какого-либо другого контейнера для построения из выражений формы {value1, value2, ...., valueN}
.
Надеюсь, что это поможет.