[英]Idiomatic ways to prevent copying non-primitive types
In Rust, non-primitive types are not copied, but are moved by default.在 Rust 中,非原始类型不会被复制,而是默认被移动。 This is great, because they're expensive to copy.这很棒,因为复制它们的成本很高。
struct Post { title: String, content: String };
let (title, content) = ("some title".to_string(), "very long post...".to_string()); // imagine they're from the user
let post = Post { title, content };
// can longer access `title` and `content`
If you really want a copy, it's simple: just clone
it (although in 99% of the cases you don't actually need to copy, and clone()
signifies an anti-pattern):如果您真的想要一个副本,这很简单:只需clone
它(尽管在 99% 的情况下您实际上不需要复制,并且clone()
表示反模式):
let post = Post { title: title.clone(), content: content.clone() };
If you write similar code in C++:如果您用 C++ 编写类似的代码:
class Post {
string title, content;
public:
Post(string t, string c) : title{ t }, content{ c }{};
};
int main() {
string title = "some title";
string content = "very long post...";
Post post(title, content);
}
The strings get copied.字符串被复制。
I know there is std::move
, but the ergonomics isn't very good, as demonstrated in this post .我知道有std::move
,但人体工程学不是很好,如这篇文章所示。 The author also suggested using shared_ptr
, but that would cause a quite large overhead (about the same as Rust's Arc
).作者还建议使用shared_ptr
,但这会导致相当大的开销(与 Rust 的Arc
大致相同)。
So the questions are, is it possible to mimic Rust's move semantics in C++?所以问题是,是否有可能在 C++ 中模仿 Rust 的移动语义? Is it idiomatic to do that?这样做是惯用的吗? If not, what are the commonly used practices to prevent copying non-primitive objects in C++?如果不是,在 C++ 中防止复制非原始对象的常用做法是什么?
There are two ways in C++ to prevent implicit copying. C++ 中有两种方法可以防止隐式复制。
As the type author, you can delete the copy constructor and copy assignment operator.作为类型作者,您可以删除复制构造函数和复制赋值运算符。 This disallows copying even when the copy is explicit.即使复制是显式的,这也不允许复制。 It is heavy-handed.它是严厉的。
As the type consumer, you can take an rvalue reference:作为类型使用者,您可以使用右值引用:
void foo(T&& t)
If foo
is passed a temporary, an implicit move happens.如果foo
是临时传递的,则会发生隐式移动。 If a copy is wanted, one can make an explicit copy either naming the type or using something like the copy
function below.如果需要副本,可以通过命名类型或使用类似于下面的copy
功能的内容来制作显式副本。 If someone wants to pass a non-temporary, both move and copy must be explicit.如果有人想传递一个非临时的,移动和复制都必须是显式的。
// one way to make a copy explicit
T copy(const T& t) { return t; }
foo(copy(get_t()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.