的std ::矢量<a> error C2582: &#39;operator =&#39; function is unavailable in</a>

时间:2012-07-03 10:54:16

标签: c++ stdvector

使用简单的向量push_back到类型A的对象 并得到这个错误, 这是我的代码:

class A 
{
    public:
    A(int a,int b,int c);
};


#include "A.h"
....
....
....
....
std::vector<A>* vec_objects = new std::vector<A>();

while(....some condition ...) 
{

    A a(1,2,3)
    vec_objects->push_back(a);
}

收到此错误:

c:\program files\microsoft visual studio 9.0\vc\include\xutility(3159) : error C2582: 'operator =' function is unavailable in 'A'
1>        c:\program files\microsoft visual studio 9.0\vc\include\xutility(3187) : see reference to function template instantiation 'void std::_Fill<A*,_Ty>(_FwdIt,_FwdIt,const _Ty &)' being compiled
1>        with
1>        [
1>            _Ty=A,
1>            _FwdIt=A *
1>        ]
1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1231) : see reference to function template instantiation 'void std::fill<A*,_Ty>(_FwdIt,_FwdIt,const _Ty &)' being compiled
1>        with
1>        [
1>            _Ty=A,
1>            _FwdIt=A *
1>        ]
1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1153) : while compiling class template member function 'void std::vector<_Ty>::_Insert_n(std::_Vector_const_iterator<_Ty,_Alloc>,unsigned int,const _Ty &)'
1>        with
1>        [
1>            _Ty=A,
1>            _Alloc=std::allocator<A>
1>        ]
1>       

我做错了什么?

3 个答案:

答案 0 :(得分:19)

vector的元素必须是:

  • 可复制,即具有与T(const T&)兼容的构造函数。
  • 可分配,即operator=operator=(const T&)兼容。
  • 默认可构造,即具有与T()兼容的构造函数。

虽然错误表明违反了可分配的要求,但代码建议不然。除非手动定义,否则每个类都会获得编译器生成的复制构造函数和赋值运算符,因此您的类实际上应该是可赋值的。但是,如果没有定义其他构造函数,则仅隐式生成默认构造函数。你有一个构造函数,因此也必须定义一个默认的构造函数。

正如迈克指出的那样,要求被简化为只能在C ++ 11中移动,但是你需要一个已经支持各自C ++ 11特性的编译器,并且必须启用这些功能。但是,错误中的路径表示Visual Studio 9.0,a.k.a Visual Studio 2008,它早于C ++ 11,因此适用限制。


默认情况下,可复制和可分配是满意的,除非你打破它们。规范说,

  • 在12.8.4中:

      

    如果类定义没有显式声明复制构造函数,则会隐式声明一个。

  • 在12.8.10中:

      

    如果类定义没有显式声明一个复制赋值运算符,则会隐式声明一个。

在这两种情况下,只有在所有基类和所有成员都具有可访问且非模糊的相应复制构造函数或复制赋值运算符时才定义它。

答案 1 :(得分:5)

您发布的代码没有任何问题。听起来你真正的类(或基类)声明了一个非公共赋值运算符。这意味着该类不可分配,因此对如何在标准容器中使用它有限制。如果它不可复制,你也会遇到问题 - 也就是说,如果声明了非公共拷贝构造函数。

在C ++ 03中,它根本无法使用。您需要使其可复制和可分配,以便在任何标准容器中使用它。

在C ++ 11中,只要它是可移动的,它就可以存储在vector中。 push_back如果也不可复制,则可能无效,在这种情况下,您可以使用emplace_back(1,2,3)push_back(std::move(a))

答案 2 :(得分:1)

您需要将operator =和copy-constructor添加到A类

class A 
{
    public:
    A(int a,int b,int c);
    A(const A& element);
    A& operator=(const A& element);     //which needs definition
};