Стандарт здесь, к сожалению, расплывчатый ([expr.static.cast] / 4, цитаты опущены):
Выражение e
может быть явно преобразовано в тип T
, если естьявляется неявной последовательностью преобразования из e
в T
, или если разрешение перегрузки для прямой инициализации объекта или ссылки типа T
из e
найдет хотя бы одну жизнеспособную функцию. […] [T] объект результата инициализируется напрямую из e
. […]
Здесь выполняются оба разрешающих условия: есть неявная последовательность преобразования (состоящая из требуемого вызова функции преобразования), и есть несколько жизнеспособных функций для прямой инициализации (потому что естьтакже последовательности неявного преобразования для различных отдельных параметров для конструкторов std::string
).
Однако, это только инициализация копии последовательности неявного преобразования, которая отказывается преобразовывать ConvSample
в (скажем) const char*
и затем std::string
, что обеспечивает однозначное средство для создания std::string
: оно специально ищет функции преобразования в целевой тип, и в то время как допускает преобразования в (скажем) const std::string&
, общие реализации не интерпретируют это как означающее, что шаблон функции преобразования должен быть создан и для этого типа и стать неоднозначным.
Прямая инициализация, которая в конечном итоге требуется, неоднозначна среди *5 конструкторов с одним аргументом 1028 * (6 для std::string_view
-как типы): ConvSample
, конечно, может быть преобразован в тип параметра для любого из них с одинаковыми «затратами».
Компиляторы, которые принимают это, применяют правила инициализации копирования (но все еще допускают * 1033). * преобразования). Те, кто отвергают его, применяют прямую инициализацию, которая, как я полагаю, в настоящее время требует формулировки. Ссылка на последовательности неявного преобразования была введена только в C ++ 17 для CWG242 , и, очевидно, расхождение реализации сохраняется в этой области.