【发布时间】:2013-12-07 14:31:50
【问题描述】:
最小的工作示例。
#include <cassert>
#include <list>
#include <queue>
//#define USE_PQ
struct MyClass
{
const char* str;
MyClass(const char* _str) : str(_str) {}
MyClass(MyClass&& src) { str = src.str; src.str = nullptr; }
MyClass(const MyClass&) = delete;
};
struct cmp_func
{
bool operator() (const MyClass&, const MyClass&) const
{
return true;
}
};
typedef std::priority_queue<MyClass, std::vector<MyClass>, cmp_func> pq_type;
#ifdef USE_PQ
MyClass remove_front(pq_type& l)
{
MyClass moved = std::move(l.top());
// error from the above line:
// use of deleted function ‘MyClass::MyClass(const MyClass&)’
l.pop();
return std::move(moved);
}
#else
MyClass remove_front(std::list<MyClass>& l)
{
MyClass moved = std::move(l.front());
l.erase(l.begin());
return std::move(moved);
}
#endif
int main()
{
const char* hello_str = "Hello World!";
MyClass first(hello_str);
#ifdef USE_PQ
pq_type l;
l.push(std::move(first));
MyClass moved = remove_front(l);
#else
std::list<MyClass> l;
l.push_back(std::move(first));
MyClass moved = remove_front(l);
#endif
assert(moved.str);
assert(!first.str);
return 0;
}
所以这行得通。现在从第 4 行删除注释符号,它说需要复制构造函数(我的被删除了)。此外,它错过了operator=。问题:
- 这里有什么区别?
- 可以解决问题吗?如果是,怎么做,如果不是,为什么不呢?
注意:你也可以使用 boost 的 priority_queue 作为你的答案,但我得到了同样的错误。
【问题讨论】:
-
priority_queue::top()返回 const 引用,因此即使移动后它仍然是左值。 -
@C.R.
std::move只是对右值引用的强制转换,因此任何const T类型的左值都将转换为const T&&,这是一个右值——即使您无法通过它获取资源。
标签: c++ c++11 move-semantics move-constructor