为什么我不能在列表迭代器上使用+ =运算符?

KiY*_*ter 3 c++ iterator stdlist c++11

我有一个来自a的迭代器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";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

li.cpp:13:10: error: no viable overloaded '+='
    iter += 3;
    ~~~~ ^  ~
1 error generated.
Run Code Online (Sandbox Code Playgroud)

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

son*_*yao 15

对于迭代器的std ::名单BidirectionalIterator,不支持operator+=RandomAccessIterator的.

你可以使用InputIterator(包括)operator++支持的东西BidirectionalIterator

++iter;
++iter;
++iter;
Run Code Online (Sandbox Code Playgroud)

但它很难看.最好的方法就像你评论的那样,使用std :: advance(或std :: next(自C++ 11))代替,它可以与InputIterator(包括BidirectionalIterator)一起使用,并且还利用了支持的功能RandomAccessIterator.

(强调我的)

复杂

线性.

但是,如果InputIt另外满足要求 RandomAccessIterator,复杂性是不变的.

所以你可以在不考虑迭代器类别的情况下使用它,std::advance为你做最好的选择.例如

std::advance(iter, 3);
Run Code Online (Sandbox Code Playgroud)

要么

iter = std::next(iter, 3);
Run Code Online (Sandbox Code Playgroud)

  • @EdChum它可能对问题的下一个观众有所帮助. (5认同)
  • OP已经在他们的代码中注释了这一点,所以使用'advance`已经知道了,所以你不需要包含这个位 (3认同)

Beg*_*ner 5

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

对于所有迭代器至少有:

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

一切取决于迭代器的类型检查表在这里:

在此输入图像描述

正如您所看到的那样,随机访问迭代器可以解决问题.