我正在尝试对实现移动赋值运算符的类的向量进行排序。此代码适用于Microsoft和Intel C ++。在GCC 4.8.1中,复制构造函数被删除,似乎导致问题。
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_algo.h:2164:11: error: use of deleted function 'constexpr MoveOnly::MoveOnly(const MoveOnly&)'
__val = _GLIBCXX_MOVE(*__i);
^
test.cpp:6:11: note: 'constexpr MoveOnly::MoveOnly(const MoveOnly&)' is implicitly declared as deleted because 'MoveOnly' declares a move constructor or move assignment operator
在Matthieu M.的帮助下,this page解释了为什么删除了复制构造函数。
#include <vector>
#include <algorithm>
#include <iostream>
#include <type_traits>
class MoveOnly {
public:
int data;
MoveOnly& operator = (const MoveOnly && rhs) {
data = rhs.data;
return *this;
}
MoveOnly& operator = (const MoveOnly & rhs) {
data = rhs.data;
return *this;
}
bool operator < (const MoveOnly& j) const {
return data<j.data;
}
};
int main() {
std::cout<<"Is move_assignable:"<<std::is_move_assignable<MoveOnly>::value<<std::endl;
std::cout<<"Is copy_assignable:"<<std::is_copy_assignable<MoveOnly>::value<<std::endl;
std::vector<MoveOnly> vMoveOnly;
//std::sort(vMoveOnly.begin(), vMoveOnly.end());
return 0;
}
答案 0 :(得分:5)
声明移动构造函数或移动赋值运算符会删除默认的复制/移动
构造函数(IMO因为鼓励我们遵守五条规则!),另一方面std::sort
需要移动构造或复制构造中的一个具有以下代码:
template<typename _RandomAccessIterator>
void
__insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last)
{
if (__first == __last)
return;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
{
if (*__i < *__first)
{
typename iterator_traits<_RandomAccessIterator>::value_type
__val = _GLIBCXX_MOVE(*__i);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
解决问题:
您需要一个可移动构建的类,您可以按is_move_constructible
进行测试,std::sort
需要第一个。使用move-constructor使其可移动构造。
至少需要一个用于赋值的移动赋值或复制赋值,以及至少一个用于构造的复制构造函数或移动构造函数。
虽然你的班级名称是MoveOnly
,但我认为选择move-assignment和move-constructor是合理的。所以,这段代码足以编译:
class MoveOnly {
...
MoveOnly(MoveOnly &&m) : data(m.data) {}
MoveOnly& operator = (const MoveOnly && rhs) { ... }
};
答案 1 :(得分:-3)
我在你的代码中添加了一些东西,这很好用:
#include <vector>
#include <algorithm>
#include <iostream>
#include <type_traits>
class MoveOnly {
public:
int data;
MoveOnly (int i):
data (i)
{}
MoveOnly (MoveOnly && rhs):
data (std::move(rhs.data))
{}
MoveOnly (const MoveOnly & rhs)=delete;
MoveOnly& operator = (MoveOnly && rhs) {
data = std::move(rhs.data);
return *this;
}
MoveOnly& operator = (const MoveOnly & rhs) {
data = rhs.data;
return *this;
}
bool operator < (const MoveOnly& j) const {
return data<j.data;
}
};
int main() {
std::cout<<"Is move_assignable:"<<std::is_move_assignable<MoveOnly>::value<<std::endl;
std::cout<<"Is copy_assignable:"<<std::is_copy_assignable<MoveOnly>::value<<std::endl;
std::vector<MoveOnly> vMoveOnly;
vMoveOnly.push_back(MoveOnly(10));
vMoveOnly.push_back(MoveOnly(666));
vMoveOnly.push_back(MoveOnly(-100));
std::sort(vMoveOnly.begin(), vMoveOnly.end());
for(std::size_t i=0;i<vMoveOnly.size();++i){std::cout<<vMoveOnly[i].data<<std::endl;}
return 0;
}
PS:使用const r值引用是一种废话,因为rvalue引用的主要目的是移动对象而不是复制它们。移动对象的状态意味着修改。所以没有const