Myrddin Krustowski
Myrddin Krustowski

Reputation: 771

How to define a function to work with move semantics and copy semantics?

Suppose that I am implementing a collection and I want to add an element to it, something like.

template <typename T>
class MyCollection
{
    void add(const T& element);
};

Now, since adding element usually means copying it, for efficiency reason it makes sense to have the following version of add as well void add(T&& element). Now the problem is that, obviously the code for both functions is exactly the same, with only difference being the argument type. My command of C++ is limited at the moment, but I would like to know whether there is a simple and idiomatic way to write the addthe function once without rewriting it twice?

Upvotes: 5

Views: 378

Answers (2)

HTNW
HTNW

Reputation: 29193

The most general solution, I think, would actually be this. This is what the standard library provides, so I suppose that makes it "idiomatic".

template<typename T>
struct my_collection {
    template<typename... Args>
    void emplace(Args&&... args) {
        // construct the T object directly in its place out of std::forward<Args>(args)...
    }
};

Upvotes: 4

bipll
bipll

Reputation: 11940

In fact this is solved by defining a single overload:

void add(T element) {
    where_it_is_actually_stored.insert(std::move(element));
}

Next, depending on whether you're adding a lvalue, a rvalue made from a moved lvalue, or a temporary object, the compiler will resolve an appropriate constructor so your value argument would be either copied or moved.

Upvotes: 6

Related Questions