initializer_list, конструкторы и фигурная инициализация - PullRequest
0 голосов
/ 30 октября 2018

Читая о различных типах инициализации, я наткнулся на одно из многочисленных странных взаимодействий std::initializer_list (предыдущий пост здесь ). Это, очевидно, простая тема, одна из первых, представленных в книгах на C ++, когда они представляют std::vector.

Дело в том, что если у вас есть один конструктор, который принимает (я думаю, только) std::initializer_list, то при инициализации скобки этот конструктор будет сильно предпочтительным: другими словами, std::vector<int> NewVect{5, 10} создаст объект, содержащий 5 и 10 , а не 5 элементов, инициализированных в 10 (std::vector<int> NewVect(5, 10)).

Особое поведение имеет место для auto инициализации скобки (auto A={1,2,3} будет выведено как std::initializer_list<int>). Теперь я не могу поверить, что в C ++ определенная обработка присваивается конкретным объектам, поскольку в моем заголовке знаний содержится только хорошо написанный и полезный фрагмент кода. Более того, эти синтаксисы не работают, если вы не можете прямо или косвенно #include <initializer_list>, даже если мой компилятор VS2017 выводит очень специальный набор ошибок, указывающий, что этот заголовок нужен для работы (вы можете легко проверить это с auto).

Итак, мой вопрос, само собой разумеющееся, что это поведение является следствием кода из заголовка списка initiliazer, и мой компилятор, вероятно, построен для использования STD, как это реализовано? Могу ли я перенаправить это поведение, чтобы оно никогда не происходило в стороне от явного вызова (то есть std::vector<int> NewVect{5, 10} будет эквивалентно std::vector<int> NewVect(5, 10), и теперь вам нужно будет вызвать std::vector<int> NewVect{std::initializer_list<int>{5, 10}})? Можно ли передать такое поведение другим классам, созданным пользователем?

1 Ответ

0 голосов
/ 30 октября 2018

считается само собой разумеющимся, что это поведение является следствием кода из заголовка списка initiliazer, и мой компилятор, вероятно, построен для использования STD, как это реализовано?

В Стандарте есть специальное правило, которое говорит что-то вроде: ", если вы используете инициализацию списка ({...}) для создания объекта, и у объекта есть конструктор, который принимает std::initializer_list этот конструктор выбран независимо от разрешения перегрузки ". Это означает, что конструкторы std::initializer_list всегда имеют приоритет над другими при использовании {...} синтаксиса инициализации.


Могу ли я перенаправить это поведение, чтобы оно никогда не происходило, кроме явного вызова

В ваших классах вы можете избежать использования std::initializer_list. Тогда такого поведения никогда не будет. Вы не можете изменить это для std:: классов.


Можно ли передать такое поведение другим классам, созданным пользователем?

Не с вашим желаемым синтаксисом, так как std::initializer_list особенный. Вы можете создать собственную альтернативу initializer_list или использовать что-то вроде variadic template constructor, чтобы заставить пользователей иметь явный синтаксис.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...