与const std :: string的向量相关的编译失败

ksl*_*ksl 15 c++ iterator stdvector c++11

请有人解释为什么以下代码不能使用clang 3.5进行编译.

报告的错误是"算法中没有可行的重载"="."

std::vector<const std::string> m_messages;
std::vector<const std::string>::iterator iter;
...

if (iter != m_messages.end())
{
    m_messages.erase(iter);      // compilation error
}
Run Code Online (Sandbox Code Playgroud)

如果我声明m_messages为:std::vector<std::string> m_messages;那么它编译好了.

另外,有什么区别:

std::vector<const std::string> m_messages;
Run Code Online (Sandbox Code Playgroud)

std::vector<std::string> m_messages;
Run Code Online (Sandbox Code Playgroud)

TIA.

Kar*_*ath 16

要擦除元素,必须重新定位右侧元素(向左移动).

由于您的字符串是const,旧元素不能被覆盖(通过=运算符)因此错误.

  • 析构函数+复制构造函数组合的问题是,如果构造函数抛出,则向量中间有一个"洞".那又怎样?摧毁那个向量会导致双重破坏一个元素 - UB!std :: vector必须首先复制或移动元素,并在操作结束时销毁任何元素,以避免产生这样的"漏洞". (3认同)
  • 如果你真的需要不可复制的对象(比如`const`),请使用基于节点的容器:`map``set``unordered_map``unordered_set``list`和`forward_list`. (2认同)

Abh*_*jit 5

这是否意味着如果可以删除元素,那么使用const字符串向量是没有意义的? Yes at least what the standard says

23.3.7.5向量修饰符[vector.modifiers]

迭代器擦除(const_iterator位置); iterator erase(const_iterator first,const_iterator last);

效果:在擦除点处或之后使迭代器和引用无效.

复杂性:T的析构函数被称为等于被擦除元素数量的次数,但T的移动赋值运算符被称为等于擦除元素之后的向量中元素数量的次数.

抛出:除非复制构造函数,移动构造函数,赋值运算符或T的移动赋值运算符抛出异常,否则无效.