问题描述
我正在尝试对实现移动分配运算符的类的向量进行排序.该代码在Microsoft和Intel C ++中可以正常工作.在GCC 4.8.1中,复制构造函数被删除,似乎引起了问题.
I'm trying to sort a vector of class that implements move assignment operator. This code works fine in Microsoft and Intel C++. In GCC 4.8.1, the copy constructor is deleted and seems causing problem.
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.的帮助下,此页面解释了为什么删除复制构造函数.
And with help from Matthieu M., this page explained why the copy constructor is deleted.
#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;
}
推荐答案
声明移动构造函数或移动赋值运算符将删除默认的复制/移动构造函数(IMO鼓励我们遵守5规则!),另一方面,std::sort
需要具有以下代码的move-construct或copy-construct之一:
Declaring a move constructor or move assignment operator deletes the default copy/move constructors (IMO due to encourage us to obey rule of five!), on the other hand std::sort
needs one of move-construct or copy-construct having this code:
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);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
要解决此问题:
To solve the issue:
您需要一个可移动构造的类,可以通过 is_move_constructible
进行测试,std::sort
需要第一个.放置一个move-constructor使其可移动.
You need a class which is move-constructable and you can test it by is_move_constructible
, std::sort
needs first one. Put a move-constructor to make it move-constructable.
您至少需要移动分配或副本分配之一来进行分配,并且至少需要复制构造器或移动构造器之一来进行构建.
You need at least one of move-assignment or copy-assignment for assignment, and at least one of copy-constructor or move-constructor for construction.
虽然您的班级名称是MoveOnly
,但我认为选择move-assignment和move-constructor是合理的.因此,此代码足以编译:
While you class name is MoveOnly
, I think it's reasonable to pick move-assignment and move-constructor. So, this code is enough to compile:
class MoveOnly {
...
MoveOnly(MoveOnly &&m) : data(m.data) {}
MoveOnly& operator = (const MoveOnly && rhs) { ... }
};
这篇关于GCC C ++ 11删除移动可分配类的副本分配会阻止std :: sort编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!