0

我在地图的键上定义了两个迭代器:

template<class MyMap>
struct MapKeyIterator : MyMap::iterator {
    using Base = typename MyMap::iterator;
    using Key = typename MyMap::key_type;
    MapKeyIterator() : Base(){};
    MapKeyIterator(Base it_) : Base(it_){};

    Key *operator->() const { return &(Base::operator->()->first); }
    Key operator*() const { return Base::operator*().first; }
};

template<class MyMap>
struct MapKeyConstIterator : MyMap::const_iterator {
    using Base = typename MyMap::const_iterator;
    using Key = typename MyMap::key_type;
    MapKeyConstIterator() : Base(){};
    MapKeyConstIterator(Base it_) : Base(it_){};

    Key *operator->() const { return &(Base::operator->()->first); }
    Key operator*() const { return Base::operator*().first; }
};

以下类型使用这些迭代器:

struct A {
    using MyMap = std::map<int, int>;
    using KeyIterator = MapKeyIterator<MyMap>;
    using KeyConstIterator = MapKeyConstIterator<MyMap>;

    KeyIterator begin() { return m.begin(); }
    KeyConstIterator cbegin() const { return m.cbegin(); }
    KeyIterator end() { return m.end(); }
    KeyConstIterator cend() const { return m.cend(); }
private:
    MyMap m{{1, 2}, {2, 4}, {3, 6}, {4, 8}};
};

以下不编译:

void f(const A &a) {
    for (const auto &el: a)
        std::cout << el << std::endl;
}

int main() {
    A a;
    f(a);
    return 0;
}

g++ 5.4.0 的错误消息显示begin使用的是cbegin. 为什么?

temp.cpp: In function ‘void f(const A&)’:
temp.cpp:68:26: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
     for (const auto &el: a)
                          ^
temp.cpp:59:17: note:   in call to ‘A::KeyIterator A::begin()’
     KeyIterator begin() { return m.begin(); }
                 ^
temp.cpp:68:26: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
     for (const auto &el: a)
                          ^
temp.cpp:61:17: note:   in call to ‘A::KeyIterator A::end()’
     KeyIterator end() { return m.end(); }
4

1 回答 1

4

基于范围的for 从不调用cbegin/ cend。这就是为什么您仍然需要返回s的/const版本。beginendconst_iterator

于 2017-01-08T19:15:37.167 回答