繁体   English   中英

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

[英]Idiomatic ways to prevent copying non-primitive types

在 Rust 中,非原始类型不会被复制,而是默认被移动。 这很棒,因为复制它们的成本很高。

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`

如果您真的想要一个副本,这很简单:只需clone它(尽管在 99% 的情况下您实际上不需要复制,并且clone()表示反模式):

let post = Post { title: title.clone(), content: content.clone() };

如果您用 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);
}

字符串被复制。

我知道有std::move ,但人体工程学不是很好,如这篇文章所示 作者还建议使用shared_ptr ,但这会导致相当大的开销(与 Rust 的Arc大致相同)。

所以问题是,是否有可能在 C++ 中模仿 Rust 的移动语义? 这样做是惯用的吗? 如果不是,在 C++ 中防止复制非原始对象的常用做法是什么?

C++ 中有两种方法可以防止隐式复制。

作为类型作者,您可以删除复制构造函数和复制赋值运算符。 即使复制是显式的,这也不允许复制。 它是严厉的。

作为类型使用者,您可以使用右值引用:

void foo(T&& t)

如果foo是临时传递的,则会发生隐式移动。 如果需要副本,可以通过命名类型或使用类似于下面的copy功能的内容来制作显式副本。 如果有人想传递一个非临时的,移动和复制都必须是显式的。

// 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM