【问题标题】:Why can't I use += operator on a list iterator?为什么我不能在列表迭代器上使用 += 运算符?
【发布时间】:2017-09-24 01:24:35
【问题描述】:

我有一个来自 std::list<std::string> 的迭代器,但是当我尝试使用 += 推进它时,出现编译错误。

代码是:

#include <list>
#include <iostream>
#include <string>
int main() {
    std::list<std::string> x;

    x.push_front("British");
    x.push_back("character");
    x.push_front("Coding is unco");
    x.push_back("Society");
    x.push_back("City Hole");
    auto iter = x.begin();
    iter += 3;
    //std::advance(iter, 3);
    x.erase(iter);

    for (auto &e: x) {
        std::cout << e << "\n";
    }
}

如果我使用 clang++ -std=c++11 -o li li.cpp 编译它,我会得到:

li.cpp:13:10: error: no viable overloaded '+='
    iter += 3;
    ~~~~ ^  ~
1 error generated.

为什么我不能在这个迭代器中使用+=

【问题讨论】:

  • @EdChum 更准确地说,您不能像这样增加列表迭代器。 (+ Op 知道提前,在评论中)
  • iter += 3 表示iter = iter + 3,你不能这样做。
  • 假设错误信息相当清楚我不太明白问题是什么
  • @Mudi -- 没有。 iter += 3 表示“调用重载运算符+=”。与数字类型不同,它与+ 没有内在联系。
  • @PeteBecker 同意!

标签: c++ c++11 iterator stdlist


【解决方案1】:

std::list 的迭代器是BidirectionalIterator,它不支持operator+=,如RandomAccessIterator

你可以使用operator++,支持InputIterator(包括BidirectionalIterator),类似

++iter;
++iter;
++iter;

但这很丑。最好的方法是正如您评论的那样,改用std::advance(或std::next(C++11 起)),它可以与InputIterator(包括BidirectionalIterator)一起使用,并且还可以利用这些功能支持RandomAccessIterator

(强调我的)

复杂性

线性。

但是,如果InputIt 还满足以下要求 RandomAccessIterator复杂性是不变的

所以你可以直接使用它而不考虑迭代器的类别,std::advance 会为你做最好的选择。例如

std::advance(iter, 3);

iter = std::next(iter, 3);

【讨论】:

  • OP 已经在他们的代码中注释掉了这个,所以 advance 的使用是已知的,所以你不需要包含这个位
  • @EdChum 这可能对问题的下一位查看者有所帮助。
  • @EdChum 我添加了一些关于std::advance 的解释。从问题(关于迭代器类别)来看,我认为 OP 可能还不够了解。
  • 好吧,老实说,当我第一次发布这个问题时,我在评论这个问题时错过了这个,所以值得强调
【解决方案2】:

std::list::iterator 不是Random Access Iterator。不可能“向前跳跃”列表中的多个元素,您必须遍历列表,直到到达所需的元素。您可以使用std::advance,它将根据迭代器类别推断出推进迭代器的最佳方式。对于std::list::iterator,它将在循环中递增迭代器。

【讨论】:

    【解决方案3】:

    原因很简单,您使用的双向迭代器没有定义 += 运算符。

    对于所有迭代器,至少有:

    • 可复制且可破坏,即X b(a);b = a;
    • 可以递增,即++aa++

    其他一切都取决于迭代器的类型检查表here

    正如您所见,随机访问迭代器可以解决问题。

    【讨论】:

      猜你喜欢
      • 2013-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      相关资源
      最近更新 更多