Это подпадает под [dcl.init]/17.6.3. , что довольно ясно показывает, что происходит после того, как разрешение перегрузки выбирает функцию преобразования:
Выбранная функция вызывается с выражением инициализатора в качестве аргумента; если функция является конструктором, вызов является значением prvalue неквалифицированной cv версии целевого типа, объект результата которого инициализируется конструктором. Вызов используется для прямой инициализации в соответствии с приведенными выше правилами объекта, который является местом назначения инициализации копирования.
В вашем случае это, в свою очередь, превращается в [dcl.init]/17.6. 1а>:
Если выражением инициализатора является значение prvalue, а версия исходного типа без уточнения cv относится к тому же классу, что и класс назначения, выражение инициализатора используется для инициализации целевого объекта.
В C++11 второй шаг вызывает конструктор перемещения, так как он не имеет маркера, соответствующего 17.6.1 C++17. Вместо этого вы снова танцуете прямую инициализацию/разрешение перегрузки а>:
Если инициализация является прямой инициализацией, [...] рассматриваются конструкторы. Перечисляются применимые конструкторы ([over.match.ctor]), а лучший из них выбирается с помощью разрешения перегрузки ([over.match]). Выбранный таким образом конструктор вызывается для инициализации объекта с выражением инициализатора или списком выражений в качестве аргумента(ов). Если конструктор не применяется или разрешение перегрузки неоднозначно, инициализация имеет неправильный формат.
Этот ход можно (и на практике) исключить; см. [class.copy]/31.
На самом деле более интересный случай
T t(s);
который в соответствии с формулировкой C++17 фактически требуется для вызова конструктора перемещения, поскольку он использует правило прямой инициализации и разрешает перегрузку конструкторов T. Это выбирает конструктор перемещения T и вызывает его для инициализации t, преобразуя s в значение T prvalue, которое материализуется во временное и привязывается к параметру конструктора перемещения. Маркер 17.6.1 просто недоступен в процессе, а маркер в C++11 [class.copy]/31 (теперь [class.copy.elision]/1), допускавший исключение в этом сценарии, был удален в C++17.
Скорее всего это дефект.
person
T.C.
schedule
01.06.2017
T), но он будет использовать конструктор перемещения, если он доступен (или полностью исключить копию, в зависимости от реализацииoperator T()он может применить NRVO). - person cdhowie   schedule 01.06.2017