Реализация std:: initializer_list
Я смотрел, как реализована initializer_list
, поэтому я нашел раздел 18.9 стандарта и нашел простой достаточно перспективный интерфейс. Я подумал, что было бы поучительно сделать мою собственную версию, которую я назвал MyNamespace::InitializerList
и прецедентом:
template<class T>
class ArrayPrinter
{
public:
ArrayPrinter(MyNamespace::InitializerList<T> list)
{
for (auto i : list) cout << i << endl;
}
};
...
ArrayPrinter ap{ {1,2,3} };
Я с удивлением обнаружил, что это не сработало, и компилятор жаловался, что не может найти подходящего конструктора (он хотел дать мне 3 аргумента, но в разделе 18.9 описывается только конструктор по умолчанию).
После небольшого ворча я обнаружил, что для того, чтобы работать, мой класс должен был называться точно std::initializer_list
. Я мог бы также добавить псевдоним std::initializer_list
в MyNamespace
, но я не мог бы алиас MyNamespace::InitializerList
как std::initializer_list
.
Кажется, что это не действительно функция поскольку она зависит от стандартной библиотеки?
Главное в моем вопросе - почему так важно имя и какие три аргумента он пытался передать конструктору?
Ответы
Ответ 1
Название важно, потому что стандарт говорит, что это так. Стандарт нуждается в некотором роде для того, чтобы вы могли сказать: "этому конструктору может быть передан бит-init-список, содержащий значения последовательности типа T". Таким образом было дано имя "std::initializer_list
".
Вы не можете создать класс, который обладает всеми языковыми свойствами initializer_list
. Вы можете создать тот, который удовлетворяет условиям типа, указанного в разделе 18.9 стандарта. Но вы заметите, что единственным конструктором, указанным здесь, является конструктор по умолчанию. Единственный способ создать initializer_list
с действительными элементами зависит от компилятора, а не от кода пользователя.
Итак, вы не можете воспроизвести все о initializer_list
. Так же, как вы не можете реплицировать std::type_info
. Стандартная библиотека С++ не является обязательной.