为容器提供只有const迭代器是否有意义?

时间:2014-08-21 08:42:56

标签: c++ c++11 iterator

我有一个类似于下一个的容器:

class MySpecialContainer
{
    std::vector<std::tuple<InternalType, Type1, Type2>> _vec;
};

其中Type1Type2在容器外部可用,InternalType仅在容器内使用。要从外部迭代元素,我使用类似于下一个的成员函数:

void MySpecialContainer::iterate(std::function<void(const Type1&, const Type2&)> fun)
{
    for(auto& it : _vec)
    {
        fun(std::get<1>(it), std::get<2>(it));
    }
}

正如您所看到的,这种方法有一些限制,例如无法迭代子范围或无法使用非变异std::algorithms

考虑MySpecialContainer元素从逻辑上考虑是不可变的,是否仅为它提供const_iterator是有意义的?

如果对第一个问题的答案是肯定的,那么......是否更好??

  1. _vec分隔为2个容器,一个用于InternalType,一个用于std::pair<Type1, Type2>,保持同步,只返回const_iterator第二个向量

  2. 保持现在的矢量并创建一个仅公开const Type1const Type2

  3. 的自定义迭代器

2 个答案:

答案 0 :(得分:3)

一个选项是公开只允许访问元素的某些字段的迭代器,例如:

#include <vector>
#include <tuple>
#include <boost/iterator/transform_iterator.hpp>

struct Type1 {};
struct Type2 {};
struct InternalType {};

class MySpecialContainer
{
    typedef std::vector<std::tuple<InternalType, Type1, Type2>> Vec;
    Vec _vec;

    struct Extractor
    {
        std::tuple<Type1&, Type2&> operator()(Vec::value_type& t) const {
            return std::tie(std::get<1>(t), std::get<2>(t));
        }

        std::tuple<Type1 const&, Type2 const&> operator()(Vec::value_type const& t) const {
            return std::tie(std::get<1>(t), std::get<2>(t));
        }
    };

public:
    typedef boost::transform_iterator<Extractor, Vec::iterator> iterator;
    typedef boost::transform_iterator<Extractor, Vec::const_iterator> const_iterator;

    iterator begin() { return iterator{_vec.begin()}; }
    iterator end() { return iterator{_vec.end()}; }
    const_iterator begin() const { return const_iterator{_vec.begin()}; }
    const_iterator end() const { return const_iterator{_vec.end()}; }
};

int main() {
    MySpecialContainer c;
    for(auto x : c) {
    }
}

请注意,通过非const迭代器,您仍然可以更新公开的值,因为trasform迭代器返回一个引用元组。

答案 1 :(得分:3)

暴露const迭代器很好。标准中甚至有优先权,因为std::set有效地做到了这一点。从技术上讲,iteratorconst_iterator可以是不同的类型,但不允许通过任何类型的迭代器修改元素,因为这可能会破坏set的不变量。