我有一个自定义容器类,我想为其编写 iterator
和 const_iterator
类。
我以前从未这样做过,也没有找到合适的方法。关于迭代器创建的指导方针是什么,我应该注意什么?
我还想避免代码重复(我觉得 const_iterator
和 iterator
共享很多东西;一个应该继承另一个吗?)。
脚注:我很确定 Boost 可以缓解这种情况,但由于许多愚蠢的原因,我不能在这里使用它。
原文由 ereOn 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个自定义容器类,我想为其编写 iterator
和 const_iterator
类。
我以前从未这样做过,也没有找到合适的方法。关于迭代器创建的指导方针是什么,我应该注意什么?
我还想避免代码重复(我觉得 const_iterator
和 iterator
共享很多东西;一个应该继承另一个吗?)。
脚注:我很确定 Boost 可以缓解这种情况,但由于许多愚蠢的原因,我不能在这里使用它。
原文由 ereOn 发布,翻译遵循 CC BY-SA 4.0 许可协议
我很想知道这是多么 _正确_,但似乎可以作为内部数据存储的滚动您自己的迭代器
template<typename T>
struct iterator_type
{
using self_type = iterator_type;
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = std::remove_cv_t<T>;
using pointer = T*;
using reference = T&;
iterator_type( pointer ptr ) noexcept
: _ptr{ ptr }
{}
reference operator*() noexcept { return *_ptr; }
pointer operator->() noexcept { return _ptr; }
self_type operator++() noexcept { ++_ptr; return *this; }
self_type operator++(int) noexcept { self_type tmp = *this; ++_ptr; return tmp; }
self_type operator--() noexcept { --_ptr; return *this; }
self_type operator--(int) noexcept { self_type tmp = *this; --_ptr; return tmp; }
bool operator==( const self_type &other ) const noexcept { return _ptr == other._ptr; }
bool operator!=( const self_type &other ) const noexcept { return _ptr != other._ptr; }
private:
pointer _ptr;
};
template<typename T>
using const_iterator_type = iterator_type<std::add_const_t<T>>;
然后我只是将这些添加到我的课程中,并且似乎按预期工作。
template<typename T>
class Container
{
public:
using iterator = iterator_type<T>;
using const_iterator = const_iterator_type<T>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
...
iterator begin() { return _begin; }
iterator end() { return _begin + _size; }
const_iterator cbegin() const { return _begin; }
const_iterator cend() const { return _begin + _size; }
reverse_iterator rbegin() { return reverse_iterator(_begin + _size); }
reverse_iterator rend() { return reverse_iterator(_begin); }
const_reverse_iterator crbegin() const { return const_reverse_iterator(_begin + _size); }
const_reverse_iterator crend() const { return const_reverse_iterator(_begin); }
private:
T* _begin;
size_t _size;
size_t _capacity;
};
the only thing is that to make it with the std::cbegin()
, std::rcbegin()
, std::cend()
and std::rcend()
functions I have to extend the std
命名空间:
namespace std
{
template<typename T>
typename Container<T>::const_iterator cbegin( Container<T> &c ) { return c.cbegin(); }
template<typename T>
typename Container<T>::const_iterator cend( Container<T> &c ) { return c.cend(); }
template<typename T>
typename Container<T>::const_reverse_iterator crbegin( Container<T> &c ) { return c.crbegin(); }
template<typename T>
typename Container<T>::const_reverse_iterator crend( Container<T> &c ) { return c.crend(); }
}
原文由 Treebeard 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.5k 阅读
1 回答3.3k 阅读
std::iterator
和random_access_iterator_tag
。这些基类定义了 STL 所需的所有类型定义并做其他工作。注意
iterator_type
和const_iterator_type
类型定义:它们是非常量和常量迭代器的类型。另请参阅: 标准库参考
编辑:
std::iterator
自 C++17 起已弃用。请参阅 此处 的相关讨论。