【问题标题】:Not able to erase vector element using iterator, vector element implements the move constructor无法使用迭代器擦除向量元素,向量元素实现移动构造函数
【发布时间】:2017-05-18 23:57:25
【问题描述】:

我有一个 struct Cache 的向量。实现 Move 构造函数的缓存。每当我尝试遍历此向量并尝试在特定条件下擦除元素时,它都无法编译。

struct Cache {
    Cache() {}

    Cache(Cache&& other)
        : serviceName(std::move(other.serviceName))
    {}

    ~Cache() {}

    size_t referenceCount;
    std::string serviceName;
};

std::vector<Cache> vectorCaches;
auto iter = vectorCaches.begin();
while(iter != vectorCaches.end()) {
     if(iter->serviceName == "Sample") {
         iter = vectorCaches.erase(iter); //compiler error here
     } else {
         iter++;
     }
}

编译器错误:

错误:使用已删除的函数 'Cache& Cache::operator=(const Cache&)' __result = std::move(__first); ^ 注意:'Cache& Cache::operator=(const Cache&)' 被隐式声明为已删除,因为 'Cache' 声明了移动 构造函数或移动赋值运算符 结构缓存 {

当矢量元素实现移动构造函数时,是否有任何解决方法来实现擦除?任何帮助表示赞赏。

【问题讨论】:

  • 尝试让你的移动构造函数noexcept。
  • @KerrekSB OP不需要定义移动赋值运算符吗?
  • @NathanOliver:确实如此。
  • @FelixLauer:break 可能不合适。线索:OP 已经竭尽全力让iter 对下一次迭代有效,并且容器是一个向量,可能包含重复项。
  • 另外请注意,在这种情况下,您不需要定义任何构造函数,如果需要,您不需要定义任何构造函数来填充缓存成员。所有其他特殊成员函数将由编译器生成。

标签: c++ c++11


【解决方案1】:

通过创建移动构造函数而不是复制构造函数,您使您的类型不可复制。

这很好,但是向量要求您的元素可以在其存储空间中被复制或移动,特别是当您从容器中移除并且所有以下元素必须被打乱时。它通过赋值来做到这一点。

因此,您可以让您的类保持可移动和不可复制,但您确实需要编写一个移动赋值运算符。

一般来说:如果你写了一个拷贝构造函数,就写一个拷贝赋值运算符;并且,如果您编写移动构造函数,请编写移动赋值运算符。

顺便说一句,你的循环坏了;如果服务名称​​不匹配,它不会通过容器。

【讨论】:

  • 一般来说,坚持基本的设计规则 (en.cppreference.com/w/cpp/language/rule_of_three) 可能有助于规避这类问题。
  • @FelixLauer:零规则更好。
  • 啊,我看到页面有一个误导性的 URI :)
  • 一个?没听说过那个
  • @GillBates:定期 Stack Exchange DB 数据转储是否计数? :D
【解决方案2】:

删除此代码:

Cache(Cache&& other)
    : serviceName(std::move(other.serviceName))
{}

它没有任何用处。它甚至看起来有问题,即使不是有问题,也非常令人惊讶。

替换为:

Cache(Cache&& other)=default;
Cache(Cache const& other)=default;
Cache& operator=(Cache&& other)=default;
Cache& operator=(Cache const& other)=default;

或者,在某些情况下,省略所有 4 个。我喜欢将它们显式地设为默认值。

编译器错误是因为创建Cache(Cache&amp;&amp;) 隐式删除了上面的其他成员函数,特别是vector.erase 使用的operator=(Cache&amp;&amp;)。

【讨论】:

  • 我已经进行了这些更改并尝试了。它解决了这个问题。这里提供的结构是一个小型化的结构,实际的结构比这个大得多,对我来说保留移动构造函数更好。无论如何感谢您的洞察力:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2021-03-05
相关资源
最近更新 更多