繁体   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