У меня есть два кода здесь, чтобы показать вам. Они представляют собой два класса, и каждый из них предоставляет Move Constructor и функцию, которая возвращает временную.
- В первом случае функция, возвращающая временные вызовы, Move Constructor
- Во втором случае функция, возвращающая временную информацию, просто сообщает компилятору выполнить копирование
Я запутался: в обоих случаях я определяю Move Constructor и случайную функцию-член, возвращающую временную. Но поведение меняется, и мой вопрос почему.
Обратите внимание, что в следующих примерах оператор < был перегружен, чтобы распечатать список (в первом случае) и двойной элемент данных (во втором случае).
ПЕРЕМЕЩЕННЫЙ КОНСТРУКТОР ПОЛУЧИТ
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;
}
Вывод:
[List] Переместить конструктор с именем
0
1
ВЫПОЛНИТЬ КОПИРОВАННОЕ ИСПРАВЛЕНИЕ
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
Я ожидал вызова Move Constructor во втором примере. В конце концов, логика для функции такая же: вернуть временную.
Кто-нибудь объяснит мне, почему это не происходит?
Как я могу справиться с копиями?
Я хочу, чтобы мой код был самым портативным, я могу, как я могу быть уверен в этих оптимизациях компилятором?