繁体   English   中英

容器 begin/end/cbegin/cend 语义,iterator/const_iterator 兼容性

[英]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;

};

现在,我正在查看beginendcbegincend的操作语义(其中amy_containerC是它的类型):

表达 返回类型 语义
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()

因为我的iteratorconst_iterator类型不兼容,因为const通过 iterator_ 的模板参数包装在iterator_器类型中,而且我的begin()不是const 现在我有一种下沉的感觉,我的实施存在根本缺陷。

我当前实现的第二个问题是要求将beginend的返回类型列为“(const_)iterator”,而我现在只注意到“(const_)”。 但是,我的beginend不返回const_iterator

因此,我的结论是,我的实现不符合Container的操作语义要求,因此在当前形式下是无效的。 现在我很难过。 :(

所以,我很困惑:

  • iteratorconst_iterator的一般兼容性要求。
  • begin()end()声明中的 cv 限定符。

我的问题是:

  1. 我的结论是否正确,即我的容器目前无法满足Container wrt 的要求。 beginendcbegincend
  2. iteratorconst_iterator类型是否需要相互可比?
  3. const_iterator是否需要从iterator中复制构造和赋值?
  4. begin()end()是否必须声明为const
  5. 我在iterator_::value_type中包装const时犯了一个错误吗?
  6. "(const_)iterator" 对于beginend的返回类型意味着什么?

我意识到这看起来像很多问题,但它们都归结为一个问题,即iteratorconst_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM