代码之家  ›  专栏  ›  技术社区  ›  Christopher Bruns

缺少gcc反向迭代器比较运算符?

  •  5
  • Christopher Bruns  · 技术社区  · 15 年前

    我在gcc的非常量容器上使用常量反向迭代器时遇到问题。嗯,只有特定版本的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 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>]()'
    

    由于Mac上GCC4.2.1的其他问题,我们需要在Mac上使用GCC4.0.1,因此简单地使用较新的编译器对我来说不是一个完美的解决方案。所以我想我需要改变我使用反向迭代器的方式。有什么建议吗?

    4 回复  |  直到 15 年前
        1
  •  10
  •   Éric Malenfant    15 年前

    这是现行标准中的一个缺陷: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280

    编辑 :详细说明一下:

    • vector::reverse_iterator 指定为 std::reverse_iterator<vector::iterator> ,及 vector::const_reverse_iterator std::reverse_iterator<vector::const_iterator> .
    • std::reverse_iterator 使用单个模板参数定义,使 reverse_iterator<iterator> reverse_iterator<const_iterator>

    const_reverse_iterator 对非常量向量调用“rend()”的结果,该向量是(非常量) reverse_iterator .

    • 反向迭代器上的关系运算符现在接受两个模板参数

    在您的情况下,一种解决方法是明确地请求rend()的const_reverse_迭代器:

    vector<char>::const_reverse_iterator r;
    const vector<char>::const_reverse_iterator crend = v.rend();
    for (r = v.rbegin(); r != crend; ++r)
        cout << *r;
    
        2
  •  2
  •   R Samuel Klatchko    15 年前

    我会尝试一些随机的事情:

    将从rend()返回的值强制转换为常量迭代器,以查看问题是否出在比较正则迭代器和常量迭代器上:

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

    如果这不起作用,将r从常量反向迭代器更改为常规反向迭代器如何。

    不知道这些是否有效,但这就是我在这种情况下会尝试的。

        3
  •  2
  •   UncleBens    15 年前

    既然迭代器必须是相同的类型才能进行比较,并且非常量容器生成非常量迭代器,为什么不同时声明和初始化结束迭代器呢。

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

        4
  •  1
  •   Jerry Coffin    15 年前

    能够 #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 代替本机库(至少对于较旧的编译器)。