В коде ниже объекта s
класса S
используется для инициализации объекта класса D
с прямой инициализацией D d(s);
, Функция преобразования S :: operator D () используется для преобразования объекта s
во временный объект типа D
, Затем gcc и clang исключают явный вызов конструктора перемещения D(&&)
, чтобы переместить этот временный объект в d
, Увидеть живой пример.
#include <iostream>
struct D;
struct S{ operator D(); };
struct D{
D(){}
D(D&&) { std::cout << "move constructor" << '\n'; }
};
S::operator D() { std::cout << "conversion function" << '\n'; return D(); }
int main()
{
S s;
D d(s);
}
Я оспариваю правильность этого решения по следующим причинам:
Если инициализация является прямой инициализацией, или если это
инициализация копии, где cv-неквалифицированная версия источника
тип — это тот же класс, или производный класс от класса
назначения, конструкторы считаются. Применимые конструкторы
перечисляются (13.3.1.3), а лучший выбирается через перегрузку
разрешение (13,3). Выбранный конструктор вызывается для инициализации
объект, с выражением инициализатора или выражением-списком в качестве его
аргумент (ы). Если конструктор не применяется, или разрешение перегрузки
неоднозначно, инициализация плохо сформирована.
Стандарт C ++ любит создавать исключения из правил, определенных в одном месте в совершенно другом месте.
Правило копирования / перемещения указано в 12.8 / 31. В вашем коде нужно исключить две операции копирования / перемещения.
Первое легко: внутри operator D
временный объект, созданный в выражении возврата, перемещается во временный объект, представляющий возвращаемое значение функции. Пуля 3 позволяет исключить этот ход.
Вторым является перемещение возвращаемого значения временной функции в d
объект. Опять же, пуля 3 разрешает исключение.
- когда временный объект класса, который не был связан со ссылкой (12.2), будет скопирован / перемещен в объект класса с тем же типом cv-unqualified, операция копирования / перемещения может быть опущена путем создания временного объекта непосредственно в цель опущенной копии / перемещения