Question

I am new to c++11 and would like to have a std::queue storing instances of class X and try to avoid unnecessary copies in push operation. In c++11, I found push() has a rvalue reference version:

void push (value_type&& val);

So does the following implementation avoids unnecessary copy of X

std::queue<X> my_queue;

for (...) { // some for loop
  X x;
  ... // some initialization of x
  my_queue.push(std::move(x));
}

compared to the following naive implementation?

std::queue<X> my_queue;

for (...) { // some for loop
  X x;
  ... // some initialization of x
  my_queue.push(x);
}
Était-ce utile?

La solution 2

If and only if X supports move semantics the first is is fine.

X might be like:

struct X {
    int value;
    X() {
        static int n;
        value = ++n;
    }

    X(X&&) = default;
    X& operator = (X&&) = default;

    X(const X&) = delete;
    X& operator = (const X&) = delete;
};

Note: No copy of X is allowed, here.

Autres conseils

The best way to answer to such question yourself is to create a probe object.

#include <iostream>
struct probe {
    probe() { std::cout << "probe()" << ((void*)this) << std::endl; }
    probe(const probe&) { std::cout << "probe(c&)" << ((void*)this) << std::endl; }
    probe(probe&&) { std::cout << "probe(&&)" << ((void*)this) << std::endl; }
    ~probe() { std::cout << "~probe()" << ((void*)this) << std::endl; }
};

and use it instead of X in the test.

I have created a playground here.

Whether or not the extra copy of anything is performed when you do std::move solely depends on what you type in the rvalue reference constructor.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top