对于第二个片段,
auto f() {
std::vector<int> v0(100000);
std::vector<int> v1(100000);
return std::make_pair(std::move(v0),std::move(v1)); // is the move needed?
}
return
返回std::make_pair()
函数的结果。那是一个 RValue。
但是,OP 的问题可能浓缩为是否(或为什么不)命名返回值优化仍然适用于v0
/v1
当返回为std::pair
.
因此,忽略了v0
/不再v1
是主题return
,而是成为std::make_pair()
. 因此,v0
/v1
是 LValues -std::move(v0), std::move(v1)
如果打算进行移动语义,则必须应用它们将它们变成 RValues。
关于大肠杆菌的演示:
#include <iostream>
template <typename T>
struct Vector {
Vector(size_t n)
{
std::cout << "Vector::Vector(" << n << ")\n";
}
Vector(const Vector&)
{
std::cout << "Vector::Vector(const Vector&)\n";
}
Vector(const Vector&&)
{
std::cout << "Vector::Vector(const Vector&&)\n";
}
};
auto f1() {
Vector<int> v(100000);
return std::move(v); // over-pessimistic
}
auto f2() {
Vector<int> v(100000);
return v; // allows NRVO
}
auto f3() {
Vector<int> v0(100000);
Vector<int> v1(100000);
return std::make_pair(v0, v1); // copy constructor called for v0, v1
}
auto f4() {
Vector<int> v0(100000);
Vector<int> v1(100000);
return std::make_pair(std::move(v0),std::move(v1)); // move constructor called for v0, v1
}
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
DEBUG(f1());
DEBUG(f2());
DEBUG(f3());
DEBUG(f4());
}
输出:
f1();
Vector::Vector(100000)
Vector::Vector(const Vector&&)
f2();
Vector::Vector(100000)
f3();
Vector::Vector(100000)
Vector::Vector(100000)
Vector::Vector(const Vector&)
Vector::Vector(const Vector&)
f4();
Vector::Vector(100000)
Vector::Vector(100000)
Vector::Vector(const Vector&&)
Vector::Vector(const Vector&&)