[英]Container begin / end / cbegin / cend semantics, iterator / const_iterator compatibility
我一直在研究自定义ReversibleContainer ,并且我认为我走在正确的轨道上,但是我在测试Container命名要求的语义时遇到了障碍,这让我认为我从根本上错误地实现了这个。 我正在使用 C++17。
特别是,我当前的实现有点像这样(请原谅错误,我在此处键入时将其浓缩为一个示例),其中:
Item
是容器持有的类型element
是类型迭代器取消引用(它可以转换为Item
)struct
在此代码段中用于整体简洁struct my_container {
using value_type = Item;
using reference = value_type &;
using const_reference = const value_type &;
using size_type = std::vector<Item>::size_type;
using difference_type = std::vector<Item>::difference_type;
struct element {
// ...
};
// V is value type, D is part of forward/reverse iterator control
template <typename V, int D> struct iterator_ {
using iterator_category = std::random_access_iterator_tag;
using value_type = V;
using reference = V &;
using pointer = V *;
using difference_type = my_container::difference_type;
iterator_ (); // custom
iterator_ (const iterator_<V,D> &) = default;
iterator_ (iterator_<V,D> &&) = default;
~iterator_ () = default;
iterator_<V,D> & operator = (const iterator_<V,D> &) = default;
iterator_<V,D> & operator = (iterator_<V,D> &&) = default;
bool operator == (const iterator_<V,D> &) const;
// ...
};
using iterator = iterator_<element, 1>;
using const_iterator = iterator_<const element, 1>;
using reverse_iterator = iterator_<element, -1>;
using const_reverse_iterator = iterator_<const element, -1>;
iterator begin ();
iterator end ();
const_iterator cbegin () const;
const_iterator cend () const;
reverse_iterator rbegin ();
reverse_iterator rend ();
const_reverse_iterator crbegin () const;
const_reverse_iterator crend () const;
};
现在,我正在查看begin
、 end
、 cbegin
和cend
的操作语义(其中a
是my_container
, C
是它的类型):
表达 | 返回类型 | 语义 |
---|---|---|
a.begin() |
(const_)迭代器 | 指向 a 的第一个元素a 迭代器 |
a.end() |
(const_)迭代器 | 指向a 的最后一个元素的迭代器 |
a.cbegin() |
const_iterator | const_cast<const C&>(a).begin() |
a.cend() |
const_iterator | const_cast<const C&>(a).end() |
我当前实现的问题是,这个从cbegin
(以及同样cend
)派生的表达式是无效的:
a.cbegin() == const_cast<const my_container&>(a).begin()
因为我的iterator
和const_iterator
类型不兼容,因为const
通过 iterator_ 的模板参数包装在iterator_
器类型中,而且我的begin()
不是const
。 现在我有一种下沉的感觉,我的实施存在根本缺陷。
我当前实现的第二个问题是要求将begin
和end
的返回类型列为“(const_)iterator”,而我现在只注意到“(const_)”。 但是,我的begin
和end
不返回const_iterator
。
因此,我的结论是,我的实现不符合Container的操作语义要求,因此在当前形式下是无效的。 现在我很难过。 :(
所以,我很困惑:
iterator
和const_iterator
的一般兼容性要求。begin()
和end()
声明中的 cv 限定符。我的问题是:
begin
、 end
、 cbegin
和cend
?iterator
和const_iterator
类型是否需要相互可比?const_iterator
是否需要从iterator
中复制构造和赋值?begin()
和end()
是否必须声明为const
?iterator_::value_type
中包装const
时犯了一个错误吗?begin
和end
的返回类型意味着什么? 我意识到这看起来像很多问题,但它们都归结为一个问题,即iterator
和const_iterator
之间的互操作性要求是什么。 我希望这篇文章有意义。
iterator begin ();
iterator end ();
const_iterator begin () const;
const_iterator end () const;
const_iterator cbegin () const;
const_iterator cend () const;
是的, const_iterator it = iterator;
应该工作(但不是相反),应该==
(我不确定第一个是强制性的,但你仍然应该这样做)。
还可以考虑编写 SCARY 迭代器,其中迭代器不是容器的子类型。
template<class T>
struct foo {
template<class U, std::enable_if_t<std::is_same_v<std::remove_cv_t<U>, std::remove_cv_t<T>>,bool> =true>
friend bool operator==( foo const& lhs, foo<U> const& rhs );
};
这是在类型之间工作的==
示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.