我是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);
}
答案 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.