我这里有两段代码给你看。它们是两个类,每个类都提供一个移动构造函数和一个返回临时值的函数。
- 在第一种情况下,返回临时的函数调用移动构造函数
- 在第二种情况下,返回临时值的函数只是告诉编译器执行复制省略
我很困惑:在这两种情况下,我都定义了一个移动构造函数和一个返回临时值的随机成员函数。但是行为发生了变化,我的问题是为什么。
请注意,在以下示例中,运算符<< 被重载以打印列表(在第一种情况下)和双数据成员(在第二种情况下)。
移动构造函数被调用
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
执行复制省略
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
在第二个示例中,我期待调用移动构造函数。毕竟函数的逻辑是一样的:返回一个临时的。
有人会解释我为什么没有发生吗?
如何处理复制省略?
我希望我的代码是最便携的,我如何确定编译器的这些优化?