从begin()而不是cbegin()获取const_iterator

时间:2017-12-13 13:29:52

标签: c++ pointers iterator overloading const-iterator

如果我取消注释该行,有人可以解释为什么以下内容无法编译 foo::const_iterator j = f.begin();,但是如果我使用行foo::const_iterator j = f.cbegin();它会编译?我正试图让这条线工作,就像我的std::vector示例一样。

#include <vector>

struct foo {
    struct node { };
    node *first = nullptr, *last = nullptr;

    struct base_iterator {
        node* ptr;
        base_iterator (node* n) : ptr(n) { }
    };

    struct iterator : base_iterator { using base_iterator::base_iterator; };

    struct const_iterator : base_iterator { using base_iterator::base_iterator; };

    iterator begin() { return iterator(first); }
    const_iterator begin() const { return const_iterator(first); }
    const_iterator cbegin() const { return const_iterator(first); }
};

// Test

int main() {
    foo f;
    foo::iterator i = f.begin();
//  foo::const_iterator j = f.begin();  // Won't compile because f is not const.
//  foo::const_iterator j = f.cbegin();  // Will compile fine.

    std::vector<int> v;
    std::vector<int>::const_iterator it = v.begin();  // Compiles even though v is not const.
}

1 个答案:

答案 0 :(得分:3)

适用于std::vector,因为所有标准库容器的迭代器都是设计以支持iterator - &gt; const_iterator次转化。它旨在模仿指针转换的工作方式。

每当您的两个迭代器是用户定义的类时,您需要显式添加它。您有两种选择:

转换构造函数:

struct iterator : base_iterator { using base_iterator::base_iterator; };

struct const_iterator : base_iterator {
   using base_iterator::base_iterator;
   const_iterator(const iterator& other) : base_iterator(other) {}
};

转化运营商:

struct const_iterator : base_iterator { using base_iterator::base_iterator; };

struct iterator : base_iterator {
  using base_iterator::base_iterator; 
  operator const_iterator() const { /* ... */ }
};