• <bdo id='wGmSK'></bdo><ul id='wGmSK'></ul>

      <small id='wGmSK'></small><noframes id='wGmSK'>

    1. <tfoot id='wGmSK'></tfoot>
      <legend id='wGmSK'><style id='wGmSK'><dir id='wGmSK'><q id='wGmSK'></q></dir></style></legend>

      <i id='wGmSK'><tr id='wGmSK'><dt id='wGmSK'><q id='wGmSK'><span id='wGmSK'><b id='wGmSK'><form id='wGmSK'><ins id='wGmSK'></ins><ul id='wGmSK'></ul><sub id='wGmSK'></sub></form><legend id='wGmSK'></legend><bdo id='wGmSK'><pre id='wGmSK'><center id='wGmSK'></center></pre></bdo></b><th id='wGmSK'></th></span></q></dt></tr></i><div id='wGmSK'><tfoot id='wGmSK'></tfoot><dl id='wGmSK'><fieldset id='wGmSK'></fieldset></dl></div>

      编写自己的 STL 容器

      Writing your own STL Container(编写自己的 STL 容器)
        <tbody id='SUr3D'></tbody>

    2. <small id='SUr3D'></small><noframes id='SUr3D'>

    3. <i id='SUr3D'><tr id='SUr3D'><dt id='SUr3D'><q id='SUr3D'><span id='SUr3D'><b id='SUr3D'><form id='SUr3D'><ins id='SUr3D'></ins><ul id='SUr3D'></ul><sub id='SUr3D'></sub></form><legend id='SUr3D'></legend><bdo id='SUr3D'><pre id='SUr3D'><center id='SUr3D'></center></pre></bdo></b><th id='SUr3D'></th></span></q></dt></tr></i><div id='SUr3D'><tfoot id='SUr3D'></tfoot><dl id='SUr3D'><fieldset id='SUr3D'></fieldset></dl></div>
        <tfoot id='SUr3D'></tfoot>
            <legend id='SUr3D'><style id='SUr3D'><dir id='SUr3D'><q id='SUr3D'></q></dir></style></legend>

              • <bdo id='SUr3D'></bdo><ul id='SUr3D'></ul>
              • 本文介绍了编写自己的 STL 容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                是否有关于如何编写与任何 STL 容器类似的新容器的指南?

                Are there guidelines on how one should write new container which will behave like any STL container?

                推荐答案

                这是我从 § 23.2.14 拼凑而成的序列伪容器 注意 iterator_category 应该是 std::input_iterator_tagstd::output_iterator_tagstd::forward_iterator_tagstd::bidirectional_iterator_tagstd::random_access_iterator_tag.另请注意,以下内容技术上比要求的更严格,但这就是想法.请注意,由于迭代器的强大功能,绝大多数标准"函数在技术上都是可选的.

                Here's a sequence pseudo-container I pieced together from § 23.2.14 Note that the iterator_category should be one of std::input_iterator_tag, std::output_iterator_tag,std::forward_iterator_tag,std::bidirectional_iterator_tag,std::random_access_iterator_tag. Also note that the below is technically more strict than required, but this is the idea. Note that the vast majority of the "standard" functions are technically optional, due to the awesomeness that is iterators.

                template <class T, class A = std::allocator<T> >
                class X {
                public:
                    typedef A allocator_type;
                    typedef typename A::value_type value_type; 
                    typedef typename A::reference reference;
                    typedef typename A::const_reference const_reference;
                    typedef typename A::difference_type difference_type;
                    typedef typename A::size_type size_type;
                
                    class iterator { 
                    public:
                        typedef typename A::difference_type difference_type;
                        typedef typename A::value_type value_type;
                        typedef typename A::reference reference;
                        typedef typename A::pointer pointer;
                        typedef std::random_access_iterator_tag iterator_category; //or another tag
                
                        iterator();
                        iterator(const iterator&);
                        ~iterator();
                
                        iterator& operator=(const iterator&);
                        bool operator==(const iterator&) const;
                        bool operator!=(const iterator&) const;
                        bool operator<(const iterator&) const; //optional
                        bool operator>(const iterator&) const; //optional
                        bool operator<=(const iterator&) const; //optional
                        bool operator>=(const iterator&) const; //optional
                
                        iterator& operator++();
                        iterator operator++(int); //optional
                        iterator& operator--(); //optional
                        iterator operator--(int); //optional
                        iterator& operator+=(size_type); //optional
                        iterator operator+(size_type) const; //optional
                        friend iterator operator+(size_type, const iterator&); //optional
                        iterator& operator-=(size_type); //optional            
                        iterator operator-(size_type) const; //optional
                        difference_type operator-(iterator) const; //optional
                
                        reference operator*() const;
                        pointer operator->() const;
                        reference operator[](size_type) const; //optional
                    };
                    class const_iterator {
                    public:
                        typedef typename A::difference_type difference_type;
                        typedef typename A::value_type value_type;
                        typedef typename const A::reference reference;
                        typedef typename const A::pointer pointer;
                        typedef std::random_access_iterator_tag iterator_category; //or another tag
                
                        const_iterator ();
                        const_iterator (const const_iterator&);
                        const_iterator (const iterator&);
                        ~const_iterator();
                
                        const_iterator& operator=(const const_iterator&);
                        bool operator==(const const_iterator&) const;
                        bool operator!=(const const_iterator&) const;
                        bool operator<(const const_iterator&) const; //optional
                        bool operator>(const const_iterator&) const; //optional
                        bool operator<=(const const_iterator&) const; //optional
                        bool operator>=(const const_iterator&) const; //optional
                
                        const_iterator& operator++();
                        const_iterator operator++(int); //optional
                        const_iterator& operator--(); //optional
                        const_iterator operator--(int); //optional
                        const_iterator& operator+=(size_type); //optional
                        const_iterator operator+(size_type) const; //optional
                        friend const_iterator operator+(size_type, const const_iterator&); //optional
                        const_iterator& operator-=(size_type); //optional            
                        const_iterator operator-(size_type) const; //optional
                        difference_type operator-(const_iterator) const; //optional
                
                        reference operator*() const;
                        pointer operator->() const;
                        reference operator[](size_type) const; //optional
                    };
                
                    typedef std::reverse_iterator<iterator> reverse_iterator; //optional
                    typedef std::reverse_iterator<const_iterator> const_reverse_iterator; //optional
                
                    X();
                    X(const X&);
                    ~X();
                
                    X& operator=(const X&);
                    bool operator==(const X&) const;
                    bool operator!=(const X&) const;
                    bool operator<(const X&) const; //optional
                    bool operator>(const X&) const; //optional
                    bool operator<=(const X&) const; //optional
                    bool operator>=(const X&) const; //optional
                
                    iterator begin();
                    const_iterator begin() const;
                    const_iterator cbegin() const;
                    iterator end();
                    const_iterator end() const;
                    const_iterator cend() const;
                    reverse_iterator rbegin(); //optional
                    const_reverse_iterator rbegin() const; //optional
                    const_reverse_iterator crbegin() const; //optional
                    reverse_iterator rend(); //optional
                    const_reverse_iterator rend() const; //optional
                    const_reverse_iterator crend() const; //optional
                
                    reference front(); //optional
                    const_reference front() const; //optional
                    reference back(); //optional
                    const_reference back() const; //optional
                    template<class ...Args>
                    void emplace_front(Args&&...); //optional
                    template<class ...Args>
                    void emplace_back(Args&&...); //optional
                    void push_front(const T&); //optional
                    void push_front(T&&); //optional
                    void push_back(const T&); //optional
                    void push_back(T&&); //optional
                    void pop_front(); //optional
                    void pop_back(); //optional
                    reference operator[](size_type); //optional
                    const_reference operator[](size_type) const; //optional
                    reference at(size_type); //optional
                    const_reference at(size_type) const; //optional
                
                    template<class ...Args>
                    iterator emplace(const_iterator, Args&&...); //optional
                    iterator insert(const_iterator, const T&); //optional
                    iterator insert(const_iterator, T&&); //optional
                    iterator insert(const_iterator, size_type, T&); //optional
                    template<class iter>
                    iterator insert(const_iterator, iter, iter); //optional
                    iterator insert(const_iterator, std::initializer_list<T>); //optional
                    iterator erase(const_iterator); //optional
                    iterator erase(const_iterator, const_iterator); //optional
                    void clear(); //optional
                    template<class iter>
                    void assign(iter, iter); //optional
                    void assign(std::initializer_list<T>); //optional
                    void assign(size_type, const T&); //optional
                
                    void swap(X&);
                    size_type size() const;
                    size_type max_size() const;
                    bool empty() const;
                
                    A get_allocator() const; //optional
                };
                template <class T, class A = std::allocator<T> >
                void swap(X<T,A>&, X<T,A>&); //optional
                

                此外,每当我制作容器时,我都会或多或少地使用这样的类进行测试:

                Also, whenever I make a container, I test with a class more or less like this:

                #include <cassert>
                struct verify;
                class tester {
                    friend verify;
                    static int livecount;
                    const tester* self;
                public:
                    tester() :self(this) {++livecount;}
                    tester(const tester&) :self(this) {++livecount;}
                    ~tester() {assert(self==this);--livecount;}
                    tester& operator=(const tester& b) {
                        assert(self==this && b.self == &b);
                        return *this;
                    }
                    void cfunction() const {assert(self==this);}
                    void mfunction() {assert(self==this);}
                };
                int tester::livecount=0;
                struct verify {
                    ~verify() {assert(tester::livecount==0);}
                }verifier;
                

                制作 tester 对象的容器,并在测试容器时调用每个对象的 function().不要创建任何全局 tester 对象.如果您的容器在任何地方作弊,这个 tester 类将 assert 并且您会知道您在某处意外作弊.

                Make containers of tester objects, and call each one's function() as you test your container. Do not make any global tester objects. If your container cheats anywhere, this tester class will assert and you'll know that you cheated accidentally somewhere.

                这篇关于编写自己的 STL 容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                What is the past-the-end iterator in STL C++?(STL C++ 中的最后迭代器是什么?)
                vector::at vs. vector::operator[](vector::at 与 vector::operator[])
                C++ equivalent of StringBuffer/StringBuilder?(C++ 等效于 StringBuffer/StringBuilder?)
                Adding types to the std namespace(将类型添加到 std 命名空间)
                Is the C++ std::set thread-safe?(C++ std::set 线程安全吗?)
                How to use std::find/std::find_if with a vector of custom class objects?(如何将 std::find/std::find_if 与自定义类对象的向量一起使用?)
              • <tfoot id='Eayek'></tfoot>
                  • <bdo id='Eayek'></bdo><ul id='Eayek'></ul>
                      <i id='Eayek'><tr id='Eayek'><dt id='Eayek'><q id='Eayek'><span id='Eayek'><b id='Eayek'><form id='Eayek'><ins id='Eayek'></ins><ul id='Eayek'></ul><sub id='Eayek'></sub></form><legend id='Eayek'></legend><bdo id='Eayek'><pre id='Eayek'><center id='Eayek'></center></pre></bdo></b><th id='Eayek'></th></span></q></dt></tr></i><div id='Eayek'><tfoot id='Eayek'></tfoot><dl id='Eayek'><fieldset id='Eayek'></fieldset></dl></div>

                      <legend id='Eayek'><style id='Eayek'><dir id='Eayek'><q id='Eayek'></q></dir></style></legend>

                          <tbody id='Eayek'></tbody>

                        <small id='Eayek'></small><noframes id='Eayek'>