[英]Container begin / end / cbegin / cend semantics, iterator / const_iterator compatibility
I've been working on a custom ReversibleContainer , and I thought I was on the right track, but I've hit a snag in testing while going through the semantics of the Container named requirements which makes me think I've fundamentally mis-implemented this.我一直在研究自定义ReversibleContainer ,并且我认为我走在正确的轨道上,但是我在测试Container命名要求的语义时遇到了障碍,这让我认为我从根本上错误地实现了这个。 I'm working with C++17.
我正在使用 C++17。
In particular, my current implementation is formed somewhat like this (pardon errors, I'm condensing it to an example as I type here), where:特别是,我当前的实现有点像这样(请原谅错误,我在此处键入时将其浓缩为一个示例),其中:
Item
is the type the container holds Item
是容器持有的类型element
is the type iterators dereference to (it's convertible to Item
) element
是类型迭代器取消引用(它可以转换为Item
)struct
is used for overall brevity in this snippet 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;
};
Now, I'm looking at the operational semantics of begin
, end
, cbegin
and cend
(where a
is a my_container
, and C
is its type):现在,我正在查看
begin
、 end
、 cbegin
和cend
的操作语义(其中a
是my_container
, C
是它的类型):
expression![]() |
return type![]() |
semantics![]() |
---|---|---|
a.begin() |
(const_)iterator ![]() |
iterator to the first element of a ![]() a 迭代器 |
a.end() |
(const_)iterator ![]() |
iterator to one past the last element of a ![]() a 的最后一个元素的迭代器 |
a.cbegin() |
const_iterator ![]() |
const_cast<const C&>(a).begin() |
a.cend() |
const_iterator ![]() |
const_cast<const C&>(a).end() |
And the problem with my current implementation is that this expression, derived from the cbegin
(and likewise cend
), is invalid:我当前实现的问题是,这个从
cbegin
(以及同样cend
)派生的表达式是无效的:
a.cbegin() == const_cast<const my_container&>(a).begin()
Because my iterator
and const_iterator
types are incompatible due to the const
being wrapped up in the iterator type via the template parameters to iterator_
, and also because my begin()
is not const
.因为我的
iterator
和const_iterator
类型不兼容,因为const
通过 iterator_ 的模板参数包装在iterator_
器类型中,而且我的begin()
不是const
。 And now I'm getting that sinking feeling that I have a fundamental flaw in my implementation.现在我有一种下沉的感觉,我的实施存在根本缺陷。
The second problem with my current implementation is that the requirements list the return type of begin
and end
as "(const_)iterator", and I am only just noticing the "(const_)" now.我当前实现的第二个问题是要求将
begin
和end
的返回类型列为“(const_)iterator”,而我现在只注意到“(const_)”。 However, my begin
and end
do not return a const_iterator
.但是,我的
begin
和end
不返回const_iterator
。
My conclusion, then, is that my implementation does not meet the operational semantics requirements of Container , and is therefore invalid in its current form.因此,我的结论是,我的实现不符合Container的操作语义要求,因此在当前形式下是无效的。 And now I'm sad.
现在我很难过。 :(
:(
So, I'm confused about:所以,我很困惑:
iterator
and const_iterator
. iterator
和const_iterator
的一般兼容性要求。begin()
and end()
. begin()
和end()
声明中的 cv 限定符。 And my questions are:我的问题是:
begin
, end
, cbegin
, and cend
? begin
、 end
、 cbegin
和cend
?iterator
and const_iterator
types need to be equality comparable with each other? iterator
和const_iterator
类型是否需要相互可比?const_iterator
need to be copy constructible and assignable from an iterator
? const_iterator
是否需要从iterator
中复制构造和赋值?begin()
and end()
have to be declared as const
? begin()
和end()
是否必须声明为const
?const
in iterator_::value_type
?iterator_::value_type
中包装const
时犯了一个错误吗?begin
and end
? begin
和end
的返回类型意味着什么? I realize that looks like a lot of questions but they all sort of boil down to the single question of what the requirements for interoperability between iterator
and const_iterator
are.我意识到这看起来像很多问题,但它们都归结为一个问题,即
iterator
和const_iterator
之间的互操作性要求是什么。 I hope this post makes sense.我希望这篇文章有意义。
iterator begin ();
iterator end ();
const_iterator begin () const;
const_iterator end () const;
const_iterator cbegin () const;
const_iterator cend () const;
And yes, const_iterator it = iterator;
是的,
const_iterator it = iterator;
should work (but not the other way around), as should ==
(I am not certain the first is mandated, but you should still do it).应该工作(但不是相反),应该
==
(我不确定第一个是强制性的,但你仍然应该这样做)。
Also consider writing SCARY iterators, where the iterator is not a subtype of the container.还可以考虑编写 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 );
};
This is an example of a ==
that works between types.这是在类型之间工作的
==
示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.