2017-01-08 5 views
0

を慣れていない私は、マップのキーの上に2回の反復子を定義している:cbeginは

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; 
} 

グラムによってエラーメッセージが++ 5.4.0 beginを用いる代わりに012されることがわかります。どうして?

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

範囲ベースfor決して通話cbegin/cend。だからこそconstbegin/endのバージョンが返され、それはconst_iteratorです。

関連する問題