std :: vector :: erase(item)是否需要为item定义赋值运算符?

时间:2014-01-23 14:15:14

标签: c++ visual-studio-2012 operators stdvector

我有一个C课,它没有定义operator=。我试图使用这样的矢量:std::vector<std::pair<C,D>> vec;。现在,我的问题是,在我完成它之后,我无法擦掉它。编译器抱怨operator=缺少C。我可以没有没有此运算符的类的向量吗?我该如何解决这个问题?我无法将作业添加到C。这是我得到的错误:

error C2582: 'operator =' function is unavailable in 'C'    C:\...\include\utility  196 1   my-lib

这是我的代码:

void Remove(const C& c) 
{
    auto i = cs_.begin();
    while( i != cs_.end()) {
        if (i->first == c) {
            cs_.erase(i);  // this is the problem
            break;
        }
        i++;
    }
 }

其中cs_是:

std::vector<std::pair<C,D>> cs_;

2 个答案:

答案 0 :(得分:5)

原因是如果您擦除与std::vector::end()不同的位置,则擦除将重新分配您的对象。重新分配意味着复制。

请注意,不可复制类型的矢量只能部分使用。在我们emplace()(前C ++ 11)之前,它甚至是不可能的。如果您的类是可复制的,那么为什么不定义赋值运算符呢?

解决方法可能是智能指针(或普通指针)的载体,如std::vector<std::unique_ptr<C>>

答案 1 :(得分:1)

这是对的。如果要erase工作,该标准要求vector或deque中的项为 MoveAssignable

通常,矢量和deques需要能够从任意位置擦除。当他们这样做时,他们需要能够将任何剩余的物品移动到被擦除物品腾出的空间中。标准说(或暗示,无论如何,通过erase上的 MoveAssignable 要求)他们通过分配来做到这一点,因此包含的项需要赋值运算符。另一个选项可以用于复制构造函数复制的项目,但这不是它的完成方式。