Ответ 1
Стандартный проект (T
есть thing
) [dcl.init.list]:
Инициализация списка - это инициализация объекта или ссылки из списка фигурных скобок....
Инициализация списка объекта или ссылки типа T определяется следующим образом:
Если braced-init-list содержит назначенный-initializer-list [не применяется]
Если T является агрегатным классом и [не применяется]
В противном случае, если T является массивом символов [не применяется]
В противном случае, если T является агрегатом [не применяется]
В противном случае, если список инициализаторов не имеет элементов [не применяется]
В противном случае, если T является специализацией
std::initializer_list<E>
[не применяется]В противном случае, если T является типом класса, учитываются конструкторы. Применимые конструкторы перечислены и одним из лучших вариантов выбираются с помощью разрешения перегрузки [применяется]
...
Когда объекты неагрегированного класса типа T инициализируются списком так, что [dcl.init.list] указывает, что разрешение перегрузки выполняется в соответствии с правилами в этом подпункте, разрешение перегрузки выбирает конструктор в два этапа:
Первоначально функции-кандидаты являются конструкторами списка инициализаторов ([dcl.init.list]) класса T, а список аргументов состоит из списка инициализаторов как единственного аргумента. [применяется]
Если жизнеспособный конструктор списка инициализаторов не найден, снова выполняется разрешение перегрузки, где все функции-кандидаты являются конструкторами класса T, а список аргументов состоит из элементов списка инициализатора.
Если список инициализаторов не имеет элементов, а T имеет конструктор по умолчанию, первая фаза опускается. [не применяется]
Обратитесь к [dcl.init.list], чтобы узнать, что такое конструктор списка инициализатора:
Конструктор является конструктором списка инициализаторов, если его первый параметр имеет тип
std::initializer_list<E>
или ссылается на, возможно, cv-квалифицированныйstd::initializer_list<E>
для некоторого типа E, и либо нет других параметров, либо все остальные параметры имеют аргументы по умолчанию ([dcl.fct.default]).
Есть также удобная заметка, которая подтверждает вывод:
Примечание: конструкторы списка инициализатора предпочтительнее других конструкторов в инициализации списка
Мой вывод:
Кандидат конструктора списка инициализатора должен рассматриваться первым и использоваться, если он действителен. Поскольку thing
неявно преобразуется в thing_ref
, она должна быть действительной. Мне кажется, что GCC соответствует.
Если вы хотите инициализировать объект типа, который имеет конструктор списка инициализаторов, но не хотите использовать этот конструктор, то не используйте инициализацию списка, то есть не используйте скобку-init-список.