Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 522
Raziel Magius Avatar asked Dec 23 '22 18:12

Raziel Magius


2 Answers

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.

like image 147
bipll Avatar answered Mar 15 '23 22:03

bipll


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)...
    }
};
like image 44
HTNW Avatar answered Mar 16 '23 00:03

HTNW