dimanche 1 mars 2020

When to std::move from *this in ref qualified method?

I am playing around with immutable objects after reading the excellent Functional Programming in C++ book. Assume I have a class for an immutable vector like this:

template<typename T>
class immutable_vector
{
public:
   immutable_vector() {}

immutable_vector<T> push_back(T t) const &
{
    immutable_vector result(*this);
    result.data.push_back(t);
    return result;
}

//What is the best way to implement this? (see below)
immutable_vector<T> push_back(T t) &&;

private:
   std::vector<T> data;

};

I know that this is a dumb way of implementing the immutable vector, but this is not the point of the question. My question is on how to implement the rvalue qualified member function push_back.

Variant 1

immutable_vector<T> push_back(T t) &&
{
    data.push_back(t);
    return std::move(*this);
}

Variant 2

immutable_vector<T> push_back(T t) &&
{
    immutable_vector<T> result(std::move(*this));
    result.data.push_back(t);
    return result;
}

This is the way the author of the book does it.

My Question

Is one way better than the other or are they completely equivalent?

My guess was that they would be equivalent, because in both cases the move constructor is called once. I would also assume that in Variant 2 copy elision would take place so that no additional constructors would be called. Am I missing something?

Aucun commentaire:

Enregistrer un commentaire