简体   繁体   中英

Idiomatic ways to prevent copying non-primitive types

In Rust, non-primitive types are not copied, but are moved by default. 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):

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

If you write similar code in 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 . The author also suggested using shared_ptr , but that would cause a quite large overhead (about the same as Rust's Arc ).

So the questions are, is it possible to mimic Rust's move semantics in C++? Is it idiomatic to do that? If not, what are the commonly used practices to prevent copying non-primitive objects in C++?

There are two ways in C++ to prevent implicit copying.

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. If a copy is wanted, one can make an explicit copy either naming the type or using something like the copy function below. 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()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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