gpt4 book ai didi

c++ - 我应该在移动构造函数/赋值运算符中使用 std::move 还是 std::forward?

转载 作者:可可西里 更新时间:2023-11-01 15:52:40 28 4
gpt4 key购买 nike

除非我错了,否则似乎两者都可以正常工作 - 是否有最佳实践理由更喜欢一个而不是另一个?

例子:

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));
}

输出:

--- B Test ---
A(A&&)
B(B&&)
--- C Test ---
A(A&&)
C(C&&)
--- D Test ---
A(const A&)
D(D&&)

最佳答案

问题是:那些真的是类的移动构造函数/赋值运算符吗? 或者它们只是从您的眼角看起来像那样?

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
};

真正的移动构造函数(#1)和移动赋值运算符(#3)中,您永远不会使用std::forward,因为,正如您正确评估的那样,你将永远移动。

请注意,如果没有完美的转发模板 (T&&),std::forward 将毫无意义。 #2 和#4 正是这种情况。在这里,您将永远不会使用 std::move,因为您不知道您实际上得到的是右值 (A-OK) 还是左值(不是很多)。

参见 this answer of mine有关 std::forward 实际工作原理的解释。

关于c++ - 我应该在移动构造函数/赋值运算符中使用 std::move 还是 std::forward?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8860233/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com