C++ 当包含对象包含唯一的\u ptr时,如何删除向量的元素?

C++ 当包含对象包含唯一的\u ptr时,如何删除向量的元素?,c++,vector,visual-studio-2013,unique-ptr,C++,Vector,Visual Studio 2013,Unique Ptr,我注意到,当包含类型包含唯一的\u ptr时,不可能删除向量的元素 例如,该类: class Bar { std::unique_ptr<int> pointerTest; Bar(Bar &bar) {}; public: Bar() { pointerTest = std::unique_ptr<int>(new int); } Bar(Bar &&bar) {

我注意到,当包含类型包含唯一的\u ptr时,不可能删除向量的元素

例如,该类:

class Bar
    {
        std::unique_ptr<int> pointerTest;

        Bar(Bar &bar) {};

    public:
        Bar() { pointerTest = std::unique_ptr<int>(new int); }
        Bar(Bar &&bar) { this->pointerTest = move(bar.pointerTest); }

        void testFunc() { pointerTest.release(); }
    };

我不能在向量上使用擦除的原因是什么?我如何解决这个问题?

问题是您的类没有正确地遵循三/五规则。可以定义复制和移动构造函数,但不能定义移动赋值运算符。这意味着不生成移动分配运算符,并且在分配时始终使用默认的复制分配运算符。但是,由于您的类有一个不可复制的成员,默认的复制分配操作符被定义为deleted,因此在使用它时会出现错误

调用它是因为从向量中删除元素会导致向量的所有后续元素发生移位(即赋值)。这通常是一个移动分配,但由于在您的类中没有定义(也没有自动生成),复制分配被调用,并且失败


我知道您使用的是Visual Studio,因此移动构造函数/移动分配操作符不会自动生成(VS还不支持标准的这一部分)。因此,要以VS兼容的方式解决此问题,请定义一个移动分配操作符。而且,在执行复制构造函数时删除它可能是一个好主意-该类看起来像是不可复制类的主要示例。

来自g++4.8.1的错误消息非常清楚:

垃圾。cpp:9:11:注意:'Bar&Bar::operator=(const Bar&)' 隐式声明为已删除,因为“Bar”声明了移动 构造函数或移动赋值运算符

通过添加“移动”操作符,问题得以解决:

class Bar
{
        std::unique_ptr<int> pointerTest;

        Bar(const Bar &);

public:
        Bar() { pointerTest = std::unique_ptr<int>(new int); }
        Bar(Bar &&bar) : pointerTest( move(bar.pointerTest)) {}
        Bar& operator=(Bar&& bar){ pointerTest = std::move(bar.pointerTest); return *this;}

        void testFunc() { pointerTest.release(); }
};
类栏
{
std::唯一指针测试;
巴(常数巴&);
公众:
Bar(){pointerTest=std::unique_ptr(new int);}
Bar(Bar&&Bar):指针测试(move(Bar.pointerTest)){}
Bar&operator=(Bar&Bar){pointerTest=std::move(Bar.pointerTest);返回*this;}
void testFunc(){pointerTest.release();}
};

FWIW,您的代码是在g++4.6下编译的。我可以在GCC4.8上通过删除不必要的移动构造函数和奇怪的复制构造函数来解决这个问题。我不知道到底是什么问题,也不知道这是否能解决编译器的问题。奇怪的是,我无法在visual studio 2013上使用或不使用“复制和移动”构造函数编译它@Mike Seymour这些构造函数有什么关联?错误很明显,它试图调用
unique\u ptr
的赋值运算符,该运算符接受常量左值引用,该引用从unique\u ptr中删除。您的代码从不调用它,可能问题出在代码中的某个地方,而您没有显示它。也许这个问题中的代码就是我编译的完整代码。您也可以在此处找到:。
for (auto &item : test123)
    item.testFunc();
class Bar
{
        std::unique_ptr<int> pointerTest;

        Bar(const Bar &);

public:
        Bar() { pointerTest = std::unique_ptr<int>(new int); }
        Bar(Bar &&bar) : pointerTest( move(bar.pointerTest)) {}
        Bar& operator=(Bar&& bar){ pointerTest = std::move(bar.pointerTest); return *this;}

        void testFunc() { pointerTest.release(); }
};