2017-04-26 83 views
3

我有一個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. 

爲什麼我不能用+=這個迭代器?

+0

@EdChum更準確地說,你不能像這樣遞增列表迭代器。 (+ Op知道前進,它在評論中) – Borgleader

+0

'iter + = 3'意思是iter = iter + 3',這是你不能做的。 – Mudi

+0

提供的錯誤信息是相當清楚我真的不明白什麼是問題 – user463035818

回答

15

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); 
+3

OP已將其代碼註釋掉了,所以使用'advance'是已知的,所以你不需要包含這個位 – EdChum

+5

@EdChum它可能對下一個查詢者有幫助。 – Beginner

+0

@EdChum我加了一些關於'std :: advance'的解釋。從問題(關於迭代器類別)我認爲OP可能不夠了解它。 – songyuanyao

3

std::list::iterator不是Random Access Iterator。無法在列表中「跳躍」幾個元素,您必須迭代列表直到達到所需元素。你可以使用std::advance這將推斷出基於迭代器類別推進迭代器的最佳方式。在std::list::iterator的情況下,它將遞增循環中的迭代器。

5

原因很簡單,+=運算符沒有爲您正在使用的雙向迭代器定義。

對於所有迭代器至少有:

  • 複印轉讓及破壞,即X b(a);b = a;
  • 可以增加,即++aa++

其他一切取決於迭代器的類型檢查表here

enter image description here

正如你看到一個隨機訪問迭代器會做的伎倆。

相關問題