У меня есть два фрагмента кода, чтобы показать вам. Это два класса, каждый из которых предоставляет конструктор перемещения и функцию, которая возвращает временное значение.
- В первом случае функция, возвращающая временное значение, вызывает конструктор перемещения.
- Во втором случае функция, возвращающая временное значение, просто говорит компилятору выполнить исключение копирования.
Я в замешательстве: в обоих случаях я определяю конструктор перемещения и случайную функцию-член, возвращающую временный объект. Но поведение меняется, и мой вопрос: почему.
Обратите внимание, что в следующих примерах оператор‹‹ был перегружен для печати списка (в первом случае) и элемента данных типа double (во втором случае).
КОНСТРУКТОР ПЕРЕМЕЩЕНИЯ ВЫЗЫВАЕТСЯ
template<typename T>
class GList
{
public:
GList() : il{ nullptr } {}
GList(const T& val) : il{ new Link<T>{ val,nullptr } } {}
GList(const GList<T>& copy) {}
GList(GList<T>&& move)
{
std::cout << "[List] Move constructor called" << std::endl;
// ... code ...
}
// HERE IS THE FUNCTION WHICH RETURNS A TEMPORARY!
GList<T> Reverse()
{
GList<T> result;
if (result.il == nullptr)
return *this;
...
...
...
return result;
}
};
int main()
{
GList<int> mylist(1);
mylist.push_head(0);
cout << mylist.Reverse();
return 0;
}
Результат:
[Список] Вызван конструктор перемещения
0
1
КОПИРОВАНИЕ ELISION ВЫПОЛНЕНО
class Notemplate
{
double d;
public:
Notemplate(double val)
{
d = val;
}
Notemplate(Notemplate&& move)
{
cout << "Move Constructor" << endl;
}
Notemplate(const Notemplate& copy)
{
cout << "Copy" << endl;
}
Notemplate Redouble()
{
Notemplate example{ d*2 };
return example;
}
};
int main()
{
Notemplate my{3.14};
cout << my.Redouble();
return 0;
}
Результат:
6.28
Я ожидал вызова конструктора перемещения во втором примере. В конце концов, логика функции та же: вернуть временное значение.
Кто-нибудь объяснит мне, почему этого не происходит?
Как бороться с копированием?
Я хочу, чтобы мой код был максимально переносимым, как я могу быть уверен в такой оптимизации компилятором?
operator<<
? - person songyuanyao   schedule 19.02.2016