简体   繁体   English

我如何在 c++ 中实现向量的迭代器插入(const_iterator position,首先是 InputIterator,最后是 InputIterator)?

[英]How can i Implement iterator insert (const_iterator position, InputIterator first, InputIterator last) of vector in c++?

Hello I am trying to make vector class in C++. and I want to make below one.你好,我正在尝试在 C++ 中制作矢量 class。我想制作下面的一个。 Can you hint me how to make?你能告诉我怎么做吗? https://www.cplusplus.com/reference/vector/vector/insert/ std::vector::insert range (3) https://www.cplusplus.com/reference/vector/vector/insert/ std::vector::insert 范围 (3)
template iterator insert (const_iterator position, InputIterator first, InputIterator last);模板迭代器插入(const_iterator position,首先是 InputIterator,最后是 InputIterator);

Here is my code.这是我的代码。 and plz let me know if there are mistakes.如果有错误,请告诉我。

#ifndef VECTOR_H
#define VECTOR_H

#include <algorithm>
#include <iostream>
#include <stdexcept>
#include "dsexceptions.h"

template <typename Object>
class Vector
{
public:
    explicit Vector(int initSize = 0)
        : theSize(initSize), theCapacity(initSize + SPARE_CAPACITY),objects(nullptr)
        
    {
        (objects = new Object[theCapacity]);
        for(int k=0; k<theSize; ++k)
        {
            objects[k] = 0;
        }
    }
    Vector(const Vector& rhs)
        : theSize(rhs.theSize), theCapacity( rhs.theCapacity ), objects( nullptr)
    {
        objects = new Object[theCapacity];
        for (int k = 0; k < theSize; ++k)
            objects[k] = rhs.objects[k];
    }

    Vector& operator= (const Vector& rhs)
    {
        Vector copy = rhs;
        std::swap(*this, copy);
        return *this;
    }

    ~Vector()
    {
        delete[] objects;
    }

    Vector(Vector&& rhs)
        : theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }
    {
        rhs.objects = nullptr;
        rhs.theSize = 0;
        rhs.theCapacity = 0;
    }

    Vector& operator= (Vector&& rhs)
    {
        std::swap(theSize, rhs.theSize);
        std::swap(theCapacity, rhs.theCapacity);
        std::swap(objects, rhs.objects);

        return *this;
    }

    bool empty() const
    {
        return size() == 0;
    }
    int size() const
    {
        return theSize;
    }
    int capacity() const
    {
        return theCapacity;
    }

    Object& operator[](int index)
    {
#ifndef NO_CHECK
        if (index < 0 || index >= size())
            throw ArrayIndexOutOfBoundsException{ };
#endif
        return objects[index];
    }

    const Object& operator[](int index) const
    {
#ifndef NO_CHECK
        if (index < 0 || index >= size())
            throw ArrayIndexOutOfBoundsException{ };
#endif
        return objects[index];
    }

    void resize(int newSize)
    {
        if (newSize > theCapacity)
            reserve(newSize * 2);
        theSize = newSize;
    }

    void reserve(int newCapacity)
    {
        if (newCapacity < theSize)
            return;

        Object* newArray = new Object[newCapacity];
        for (int k = 0; k < theSize; ++k)
            newArray[k] = std::move(objects[k]);

        theCapacity = newCapacity;
        std::swap(objects, newArray);
        delete[] newArray;
    }

    // Stacky stuff
    void push_back(const Object& x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);
        objects[theSize++] = x;
    }
    // Stacky stuff
    void push_back(Object&& x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);
        objects[theSize++] = std::move(x);
    }

    void pop_back()
    {
        if (empty())
            throw UnderflowException{ };
        --theSize;
    }

    const Object& back() const
    {
        if (empty())
            throw UnderflowException{ };
        return objects[theSize - 1];
    }

    // Iterator stuff: not bounds checked
    typedef Object* iterator;
    typedef const Object* const_iterator;

    iterator begin()
    {
        return &objects[0];
    }
    const_iterator begin() const
    {
        return &objects[0];
    }
    iterator end()
    {
        return &objects[size()];
    }
    const_iterator end() const
    {
        return &objects[size()];
    }

    static const int SPARE_CAPACITY = 2;

    /*************************************************************************/
    /*************************************************************************/
 
    iterator insert(const_iterator position, const Object& val)
    {
        if (theSize == theCapacity)
        {
            reserve(2 * theCapacity + 1);
        }
        int index = position - objects;
        for (int i = theSize - 1; i >= index; --i)
            objects[i + 1] = objects[i];
        objects[index] = val;
        theSize++;

        return &objects;
        
    }

    iterator insert(const_iterator position, Object&& val)
    {
        if (theSize == theCapacity)
        {
            reserve(2 * theCapacity + 1);
        }
        int index = position - objects;
        for (int i = theSize-1; i>=index; --i)
            objects[i+1] = objects[i];
        objects[index] = std::move(val);
        theSize++;

        return objects;
    }

That particular overload is a tricky thing, because it requires you to accept the most general kind of iterator, but people will expect better performance with other iterator types.这种特殊的重载是一件棘手的事情,因为它要求您接受最通用的迭代器类型,但人们会期望其他迭代器类型具有更好的性能。

The naive way is to loop from first to last , insert ing each element.天真的方法是从firstlast循环, insert每个元素。

template<typename InputIterator>
void insert(const_iterator position, InputIterator first, InputIterator last) {
    for (; first != last; ++first) {
         position = insert(position, *first);
    }
}

However this may require multiple reallocations.然而,这可能需要多次重新分配。 You must do that with InputIterator s, because they don't necessarily support multiple passes, but it would be really useful to reserve enough space ahead of time.必须使用InputIterator执行此操作,因为它们不一定支持多次传递,但提前预留足够的空间确实很有用。

You can have an extra overload that only applies to ForwardIterator s, which do support multiple passes, so you can know how much capacity is needed.您可以有一个仅适用于支持多次传递的ForwardIterator的额外重载,因此您可以知道需要多少容量。

With C++20 this can be done by having overloads with constrained template types在 C++20 中,这可以通过使用受限模板类型进行重载来完成

template<std::input_iterator InputIterator>
void insert(const_iterator position, InputIterator first, InputIterator last) {
    for (; first != last; ++first) {
         position = insert(position, *first);
    }
}

template<std::forward_iterator ForwardIterator>
void insert(const_iterator position, ForwardIterator first, ForwardIterator last) {
    auto requiredCapacity = theSize + std::distance(first, last);
    if (requiredCapacity > theCapacity) {
        auto index = std::distance(objects, position);
        reserve(requiredCapacity);
        position = objects + index;
    }
    for (; first != last; ++first) {
         position = insert(position, *first);
    }
}

Prior to C++20 you can have the public insert dispatch to one of two private implementations在 C++20 之前,您可以将公共insert分派到两个私有实现之一

template<typename InputIterator>
void insert(const_iterator position, InputIterator first, InputIterator last) {
    insert_impl(position, first, last, std::iterator_traits<InputIterator>::iterator_category{});
}

template<typename InputIterator>
void insert_impl(const_iterator position, InputIterator first, InputIterator last, std::input_iterator_tag) {
    for (; first != last; ++first) {
         position = insert(position, *first);
    }
}

template<typename ForwardIterator>
void insert_impl(const_iterator position, ForwardIterator first, ForwardIterator last, std::forward_iterator_tag) {
    auto requiredCapacity = theSize + std::distance(first, last);
    if (requiredCapacity > theCapacity) {
        auto index = std::distance(objects, position);
        reserve(requiredCapacity);
        position = objects + index;
    }
    for (; first != last; ++first) {
         position = insert(position, *first);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在 c++ 中实现 vector 的擦除(迭代器擦除(首先是 const_iterator,最后是 const_iterator)) - How can I implements erase( iterator erase(const_iterator first, const_iterator last)) of vector in c++ c ++编译错误“要求&#39;_InputIterator std :: __ find_if(_InputIterator,_InputIterator,_Predicate,std :: input_iterator_tag)” - c++ compile error “required from '_InputIterator std::__find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) ” C ++:如何编写const_iterator? - C++ : How to write a const_iterator? std :: vector(InputIterator是第一个,InputIterator是最后的)线性时间复杂度? - Is std::vector(InputIterator first, InputIterator last) linear time complexity? 如何在C ++中复制const_iterator - How to copy a const_iterator in C++ const_iterator 到迭代器 C++ 错误 - const_iterator to iterator C++ Error C++ 迭代器到 const_iterator - C++ iterator to const_iterator 如何在C ++中将DRY原则应用于迭代器? (iterator,const_iterator,reverse_iterator,const_reverse_iterator) - How do I apply the DRY principle to iterators in C++? (iterator, const_iterator, reverse_iterator, const_reverse_iterator) C ++ std :: vector :: const_iterator问题 - C++ std::vector::const_iterator issue 向量const_iterator如何越过向量结束? - How can vector const_iterator go past vector end?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM