我是否可以轻松覆盖 (STL) 迭代器的类别?
Can I easily override an (STL) iterator's category?
现在,我有一个类可以通过随机访问迭代器满足API要求。 但是,我可以设想一种情况,即实现将发生变化,并且只能提供前向迭代器。
因此,我想限制调用者使用随机访问功能。 我知道我可以编写自己的实现(例如restricted_bar_iterator),但想知道是否有更简单的东西(即需要更少的编码)。
class BAR { ... };
class FOO {
public:
// Bad...clients may expect 'bar_iterator' to be random access...
typedef std::vector<BAR>::iterator bar_iterator;
bar_iterator begin_bar() const;
bar_iterator end_bar() const;
// Possible solution here!
class restricted_bar_iterator :
public std::iterator< std::forward_iterator_tag, BAR > { ... };
};
void baz()
{
FOO foo;
bar_iterator it = foo.begin_bar() + 5; // want a compile time error here!
}
下面是使用Boost Iterator Adaptor的示例。我用int
而不是BAR
.
#include <boost/iterator/iterator_adaptor.hpp>
#include <vector>
struct iterator :
public boost::iterator_adaptor<
iterator, // the name of our class, see docs for details
std::vector<int>::iterator, // underlying base iterator
boost::use_default, // for value type
boost::forward_traversal_tag // all the boilerplate for this!
>
{
// need this to convert from vector::iterator to ours
explicit iterator(std::vector<int>::iterator i)
: iterator::iterator_adaptor_(i) {}
};
int main()
{
std::vector<int> v;
iterator it(v.begin());
++it; // OK
it += 1; // ERROR
}
这有效地使用 std::vector<T>::iterator
作为基类,但只允许为前向迭代器定义的操作。缺点是错误消息 - 它们不是很漂亮。
您肯定必须进行一些编码,但您可能能够从底层类型继承以获取大部分功能,只需覆盖您不想使用的操作,方法是将它们定义为在 C++11 中删除或在 C++03 中将它们设为私有且未实现:
class FOO {
// Bad...clients may expect 'bar_iterator' to be random access...
typedef std::vector<BAR>::iterator bar_iterator_impl;
public:
// Possible solution here!
struct bar_iterator : bar_iterator_impl {
bar_iterator& operator++() {
++static_cast<bar_iterator_impl&>(*this);
return *this;
}
bar_iterator operator++(int) {
bar_iterator copy(*this);
++*this;
return copy;
}
typedef std::forward_iterator_tag iterator_category;
typedef std::iterator_traits<bar_iterator_impl>::value_type value_type;
typedef std::iterator_traits<bar_iterator_impl>::difference_type difference_type;
typedef std::iterator_traits<bar_iterator_impl>::pointer pointer;
typedef std::iterator_traits<bar_iterator_impl>::reference reference;
private:
friend void operator+(bar_iterator const&, long);
friend void operator+(long, bar_iterator const&);
friend void operator-(bar_iterator const&, long);
friend void operator-(long, bar_iterator const&);
};
bar_iterator begin_bar() const;
bar_iterator end_bar() const;
};
但是,这仅在std::vector<BAR>::iterator
是类类型时才有效,并且它可以是一个指针,在这种情况下,它不能派生。要实现可移植性,您需要自己定义整个迭代器 API。
相关文章:
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- "迭代器"和"const_iterator"不是 STL 容器的必需成员?
- 没有 STL 容器的迭代器
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 迭代器 STL C++是模板、类还是接口?
- 为什么我们不在 STL 的迭代器中传递星号(*)
- 成员函数不能为集合迭代器和const_iterator的输入重载(但可以为其他 STL 迭代器重载)
- 如何在C++中重新实现包含指针的 STL 容器的类的迭代器
- C++如何获取传递给函数(STL 迭代器)的参数的名称
- 迭代器和 STL 容器的关系
- C++ 中 STL 中迭代器的大小(以字节为单位)是多少
- 如何将 stl 迭代器与特征一起使用?
- 用于 STL 迭代器、指针和 std::nullptr_t 的模板函数
- 在 stl 容器包装器中定义迭代器类型
- 在多个 STL 对对象上创建迭代器
- 如何为获取 stl 容器迭代器的函数提供函数签名?
- 在 stl 算法中移动迭代器
- lower_bound 在 C++ STL 中返回迭代器,即使元素不存在也是如此.如何避免这种情况?
- 并行STL插入迭代器,例如std :: back_insert_iterator
- STL 迭代器继承:"value_type"不命名类型