[英]Should I use std::move or std::forward in move ctors/assignment operators?
Unless I'm wrong it seems like either works just fine - is there a best practice reason to prefer one over the other? 除非我错了,否则它们似乎都运行得很好 - 是否有一个最佳实践理由更喜欢一个而不是另一个?
Example: 例:
struct A
{
A(){}
A(const A&){ std::cout << "A(const A&)\n"; }
A(A&&){ std::cout << "A(A&&)\n"; }
};
struct B
{
B(){}
B(const B& right) : x(right.x){ std::cout << "B(const B&)\n"; }
B(B&& right) : x(std::forward<A>(right.x)){ std::cout << "B(B&&)\n"; }
A x;
};
struct C
{
C(){}
C(const C& right) : x(right.x){ std::cout << "C(const C&)\n"; }
C(C&& right) : x(std::move(right.x)){ std::cout << "C(C&&)\n"; }
A x;
};
struct D
{
D(){}
D(const D& right) : x(right.x){ std::cout << "D(const D&)\n"; }
D(D&& right) : x(right.x){ std::cout << "D(D&&)\n"; }
A x;
};
int main()
{
std::cout << "--- B Test ---\n";
B b1;
B b2(std::move(b1));
std::cout << "--- C Test ---\n";
C c1;
C c2(std::move(c1));
std::cout << "--- D Test ---\n";
D d1;
D d2(std::move(d1));
}
Output: 输出:
--- B Test ---
A(A&&)
B(B&&)
--- C Test ---
A(A&&)
C(C&&)
--- D Test ---
A(const A&)
D(D&&)
The question is: Are those really the move constructor / assignment operator for the class? 问题是:那些真的是类的移动构造函数/赋值运算符吗? Or do they only look like that from the corner of your eye?
或者他们只是从你的眼角看起来像那样?
struct X{
X(X&&); // move ctor #1
template<class T>
X(T&&); // perfect forwarding ctor #2
X& operator=(X&&); // move assignment operator #3
template<class T>
X& operator=(T&&); // perfect forwarding ass. operator #4
};
In a real move ctor (#1) and move assignment operator (#3), you will never use std::forward
, since, as you correctly assessed, you will always move. 在真正的移动ctor(#1)和移动赋值运算符(#3)中,你永远不会使用
std::forward
,因为正如你正确评估的那样,你将永远移动。
Note that std::forward
never makes sense without a perfect forwarding template ( T&&
). 请注意,没有完美的转发模板(
T&&
), std::forward
永远不会有意义。 That is exactly the case for #2 and #4. 这正是#2和#4的情况。 Here, you will never use
std::move
, since you don't know if you actually got an rvalue (A-OK) or an lvalue (not so much). 在这里,你永远不会使用
std::move
,因为你不知道你是否真的得到了右值(A-OK)或左值(不是那么多)。
See this answer of mine for an explanation of how std::forward
actually works. 请参阅我的这个答案,了解
std::forward
实际上是如何工作的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.