简体   繁体   English

防止复制非原始类型的惯用方法

[英]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.

相关问题 非原始盒装类型的运算符 - Operators for non-primitive boxed types 理解非原始数据类型 - Making sense of non-primitive data types 如何强类型定义非基本类型? - How do I strongly typedef non-primitive types? 为什么隐式转换对非原始类型不明确? - Why is implicit conversion not ambiguous for non-primitive types? 是否可以处理可变函数中的非原始类型? - Is it possible to handle non-primitive types in a variadic function? C ++按值传递非原始类型? - C++ pass-by-value with non-primitive types? 如何有效地将std :: atomic <>用于非原始类型? - How to use std::atomic<> effectively for non-primitive types? 用C#中的非原始类型重新创建C ++联合类型的对齐错误 - Alignment error recreating C++ union type with non-primitive types in C# 如何使用 GraalVM 从 C++ 调用具有非原始类型作为参数的 Java 入口点方法 - How to call a Java entrypoint method with non-primitive types as parameters from C++ using GraalVM 将复杂的、非原始的 C++ 数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法 - Casting complex, non-primitive C++ data types into Erlang/Elixir format, to export methods using NIF
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM