C++ 将元素推入std::queue时避免复制

C++ 将元素推入std::queue时避免复制,c++,c++11,stl,move,C++,C++11,Stl,Move,我是c++11新手,希望有一个类X的存储实例,并尽量避免在操作中出现不必要的副本。在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

我是c++11新手,希望有一个类
X
的存储实例,并尽量避免在操作中出现不必要的副本。在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 my_queue;
for(…){//some for循环
X;
…//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);
}
std::queue my_queue;
for(…){//some for循环
X;
…//x的一些初始化
my_queue.push(x);
}

当且仅当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。

自己回答此类问题的最佳方法是创建一个探测对象

#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; }
};
#包括
结构探针{

probe(){std::cout非常感谢您提供了有趣的示例代码!因此,在您的输出中,析构函数被调用了两次。一个来自
p
,另一个来自推送到队列中的实例吗?是的,这取决于您是否使用
std::move
探测(探测常量&)
探测(探测&)为排队对象调用了