GCC C ++ 11删除移动可分配类的副本分配崩溃std :: sort? [英] GCC C++11 deleting copy assignment for move assignable classes crashes std::sort?

查看:364
本文介绍了GCC C ++ 11删除移动可分配类的副本分配崩溃std :: sort?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想排序一个实现移动赋值运算符的类的向量。此代码在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;
}


推荐答案

声明移动构造函数或移动赋值运算符删除默认的copy / move
构造函数(因为鼓励我们遵守规则五!),另一方面 std :: sort 需要一个具有此代码的移动构造或复制构造:

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 需要第一个。

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分配和移动构造函数。所以,这段代码足以编译:

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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆