将元素推入std :: queue时避免使用copys

时间:2014-02-12 23:40:43

标签: c++ c++11 stl move

我是c ++ 11的新手,希望有一个std::queue存储类X的实例,并尝试在push操作中避免不必要的副本。在c ++ 11中,我发现push()有一个右值引用版本:

void push (value_type&& val);

以下实现也避免了X

的不必要副本
std::queue<X> my_queue;

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

与以下幼稚实施相比?

std::queue<X> my_queue;

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

2 个答案:

答案 0 :(得分:3)

自己回答这个问题的最好方法是创建一个探测对象。

#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; }
};

并在测试中使用它代替X.

我创建了一个游乐场here

执行std::move时是否执行任何额外副本完全取决于您在右值参考构造函数中键入的内容。

答案 1 :(得分:2)

当且仅当X支持移动语义时,第一个是正常的。

X可能像:

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;
};

注意:此处不允许复制X.