[英]How can I implements erase( iterator erase(const_iterator first, const_iterator last)) of vector in c++
[英]How can i Implement iterator insert (const_iterator position, InputIterator first, InputIterator last) of vector in c++?
你好,我正在嘗試在 C++ 中制作矢量 class。我想制作下面的一個。 你能告訴我怎么做嗎? https://www.cplusplus.com/reference/vector/vector/insert/ std::vector::insert 范圍 (3)
模板迭代器插入(const_iterator position,首先是 InputIterator,最后是 InputIterator);
這是我的代碼。 如果有錯誤,請告訴我。
#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;
}
這種特殊的重載是一件棘手的事情,因為它要求您接受最通用的迭代器類型,但人們會期望其他迭代器類型具有更好的性能。
天真的方法是從first
到last
循環, insert
每個元素。
template<typename InputIterator>
void insert(const_iterator position, InputIterator first, InputIterator last) {
for (; first != last; ++first) {
position = insert(position, *first);
}
}
然而,這可能需要多次重新分配。 您必須使用InputIterator執行此操作,因為它們不一定支持多次傳遞,但提前預留足夠的空間確實很有用。
您可以有一個僅適用於支持多次傳遞的ForwardIterator的額外重載,因此您可以知道需要多少容量。
在 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);
}
}
在 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.