gpt4 book ai didi

c++ - 为什么我们复制然后 move ?

转载 作者:IT老高 更新时间:2023-10-28 11:56:02 24 4
gpt4 key购买 nike

我在某处看到有人决定复制一个对象并随后将其 move 到类的数据成员的代码。这让我感到困惑,因为我认为 move 的全部目的是避免复制。示例如下:

struct S
{
S(std::string str) : data(std::move(str))
{}
};

这是我的问题:

  • 我们为什么不对 str 进行右值引用?
  • 拷贝不会很贵,尤其是考虑到像 std::string 这样的东西?
  • 作者决定复制然后搬家的原因是什么?
  • 我应该什么时候自己做?

最佳答案

在我回答您的问题之前,您似乎弄错了一件事:在 C++11 中按值(value)取值并不总是意味着复制。如果传递了一个右值,它将被 move (如果存在可行的 move 构造函数)而不是被复制。 std::string 确实有一个 move 构造函数。

与 C++03 不同,在 C++11 中,按值获取参数通常是惯用的,原因我将在下面解释。另见 this Q&A on StackOverflow有关如何接受参数的更通用的指南。

Why aren't we taking an rvalue-reference to str?

因为这样会导致无法传递左值,例如:

std::string s = "Hello";
S obj(s); // s is an lvalue, this won't compile!

如果S只有一个接受右值的构造函数,上面的就不会编译。

Won't a copy be expensive, especially given something like std::string?

如果你传递一个右值,它会被 move str,最终会被 move 到data。不会进行复制。另一方面,如果您传递一个左值,该左值将被复制str,然后 move 到 data

所以总结一下,右值的两个 move ,一个拷贝和一个左值的 move 。

What would be the reason for the author to decide to make a copy then a move?

首先,正如我上面提到的,第一个并不总是拷贝;这就是说,答案是:“因为它是高效的(std::string 对象的 move 很便宜)并且简单”。

在 move 成本低廉的假设下(此处忽略 SSO),在考虑此设计的整体效率时,它们实际上可以被忽略。如果我们这样做,我们有一个左值拷贝(如果我们接受一个对 const 的左值引用,我们就会有一个拷贝)并且没有右值拷贝(如果我们接受一个左值,我们仍然会有一个拷贝引用 const)。

这意味着当提供左值时,按值取值与按左值引用 const 一样好,而在提供右值时更好。

P.S.:为了提供一些上下文,我相信 this is the Q&A OP指的是。

关于c++ - 为什么我们复制然后 move ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16724657/

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