簡體   English   中英

gcc reverse_iterator比較運算符丟失了嗎?

[英]gcc reverse_iterator comparison operators missing?

我在使用gcc的非const容器上使用const反向迭代器時遇到問題。 好吧,只有某些版本的gcc。

#include <vector>
#include <iostream>

using namespace std;

int main() {
    const char v0[4] = "abc";
    vector<char> v(v0, v0 + 3);

    // This block works fine
    vector<char>::const_iterator i;
    for (i = v.begin(); i != v.end(); ++i)
        cout << *i;
    cout << endl;

    // This block generates compile error with gcc 3.4.4 and gcc 4.0.1
    vector<char>::const_reverse_iterator r;
    for (r = v.rbegin(); r != v.rend(); ++r)
        cout << *r;
    cout << endl;

    return 0;
}

這個程序編譯好並運行gcc 4.2.1(Mac Leopard)和Visual Studio 8和9(Windows)以及gcc 4.1.2(Linux)。

但是,gcc 3.4.4(cygwin)和gcc 4.0.1(Mac Snow Leopard)存在編譯錯誤。

test.cpp:18: error: no match for 'operator!=' in 'r != std::vector<_Tp, _Alloc>::rend() [with _Tp = char, _Alloc = std::allocator<char>]()'

這是早期版本的gcc中的錯誤嗎?

由於Mac上的gcc 4.2.1存在其他問題,我們需要在Mac上使用gcc 4.0.1,因此簡單地使用較新的編譯器對我來說不是一個完美的解決方案。 所以我想我需要改變我使用反向迭代器的方式。 有什么建議?

這是當前標准的一個缺陷: http//www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280

編輯 :詳細說明:問題在於,在當前標准中:

  • vector::reverse_iterator指定為std::reverse_iterator<vector::iterator>vector::const_reverse_iteratorstd::reverse_iterator<vector::const_iterator>
  • std::reverse_iterator上的關系運算符是使用單個模板參數定義的,這使得reverse_iterator<iterator>reverse_iterator<const_iterator>不可比較。

在您的代碼中,將const_reverse_iterator與在非const向量上調用“rend()”的結果進行比較,該向量是(非const) reverse_iterator

在C ++ 0x中,進行了兩個相關的更改來修復這樣的問題:

  • reverse_iterator上的關系運算符現在有兩個模板參數
  • 像vector這樣的容器有額外的方法來明確地請求一個const_iterator:cbegin(),cend(),crbegin()和crend()。

在您的情況下,解決方法是明確請求const_reverse_iterator為rend():

vector<char>::const_reverse_iterator r;
const vector<char>::const_reverse_iterator crend = v.rend();
for (r = v.rbegin(); r != crend; ++r)
    cout << *r;

隨便的事我會嘗試:

將rend()的返回值轉換為const_reverse_iterator,以查看問題是在比較常規迭代器還是常量迭代器:

r != static_cast<vector<char>::const_reverse_iterator>(v.rend())

如果這不起作用,如何將r從const_reverse_iterator更改為常規反向迭代器。

不知道這些是否有效,但這就是我在這種情況下嘗試的。

由於迭代器需要是可比較的相同類型,並且非const容器產生非const迭代器,為什么不同時聲明和初始化結束迭代器。

for (vector<char>::const_reverse_iterator r = v.rbegin(), end_it = v.rend(); r != end_it; ++r)
    cout << *r;

使用較舊的編譯器,這甚至可以帶來很小的性能優勢。

可能是gcc舊版本中的一個錯誤,但我的猜測是錯誤存在於你的代碼中 - 你沒有#include <iterator> 如果修復不能解決問題,可能只值得進一步研究。

另一方面,如果您正在使用如圖所示的reverse_iterator (即循環體是cout << *r; ),您應該只使用std::copy

std::ostream_iterator<char> output(std::cout);

// frontwards
std::copy(v.begin(), v.end(), output);

// backwards
std::copy(v.rbegin(), v.rend(), output);

還有一個copy_backwards ,但我不相信它會做你想要的。

編輯:另一種可能需要考慮的方法:如果添加所需的標頭不起作用,並且您確實需要反向迭代器,則可以考慮使用STLPort代替本機庫(至少對於較舊的編譯器)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM