[英]How can I implements erase( iterator erase(const_iterator first, const_iterator last)) of vector in c++
https://www.cplusplus.com/reference/vector/vector/erase/我想在 c++ 中制作 vector 的 erase() 方法
iterator erase(const_iterator position)
{
theSize--;
int index = position - begin();
Object* newObj = new Object[theCapacity];
for (int i = 0, j = 0; j <= index; ++j)
{
if (j != index)
newObj[i++] = objects[j];
}
std::swap(objects, newObj);
delete[] newObj;
return &objects[index];
}
首先,我嘗試制作 erase() 並嘗試重用它來制作迭代器擦除(首先是 const_iterator,最后是 const_iterator)
iterator erase(const_iterator first, const_iterator last)
{
int index = last - begin();
for (auto it = first; it != last; ++it)
{
erase(it);
}
return objects;
}
我不知道我的做法對不對。 由於返回值是垃圾值。 我認為我的索引是錯誤的。 我如何改進我的**迭代器擦除(const_iterator 位置)**以及我如何重用我的迭代器擦除(const_iterator 位置)來使迭代器擦除(首先是 const_iterator,最后是 const_iterator)?
v.erase(v.begin(),v.begin()+3)
輸入541234
output -842150451-842150451
預計1234
您不需要重新分配數組; 改用移動語義。 即使您使用當前的實現,您也可以從舊數組中移動值而不是復制它們中獲益。
此外, erase(const_iterator, const_iterator)
接收自己的實現更有效。
您在這里的實際問題是,您通過調用erase
來使迭代器無效,正如@UlrichEckhardt 所指出的那樣,即使您沒有重新分配數組,您也需要first
調用 erase 而不是it
,因為擦除元素在它的當前 position 處it
將剩余的元素移動一個,導致下一個要擦除的元素被放置在it
的當前 position 處,而不是下一個 position 處。
這是一個應該工作的簡化矢量實現:
template<class T>
class Vector
{
public:
using iterator = T*;
using const_iterator = T const*;
Vector(std::initializer_list<T>&& list)
: size(list.size()),
objects(size == 0 ? nullptr : new T[size])
{
auto out = objects;
for (auto& e : list)
{
*out = std::move(e);
++out;
}
}
~Vector()
{
delete[] objects;
}
iterator begin() noexcept
{
return objects;
}
iterator end() noexcept
{
return objects + size;
}
const_iterator cbegin() const noexcept
{
return objects;
}
const_iterator cend() const noexcept
{
return objects + size;
}
iterator erase(const_iterator pos)
{
auto const result = objects + std::distance(cbegin(), pos);
auto const endIter = end();
for (auto p = result; p != endIter;)
{
auto& lhs = *p;
++p;
lhs = std::move(*p);
}
--size;
return result;
}
iterator erase(const_iterator first, const_iterator last)
{
auto const result = objects + std::distance(cbegin(), first);
if (first == last)
{
// empty delete sequence
return result;
}
// shift the elements after last
auto writeIter = result;
auto readIter = objects + std::distance(cbegin(), last);
for (auto const endIter = end(); readIter != endIter; ++writeIter, ++readIter)
{
*writeIter = std::move(*readIter);
}
// remove extra elements from the end
size = std::distance(objects, writeIter);
return result;
}
private:
size_t size;
T* objects;
};
int main()
{
{
Vector<int> a = { 1, 2, 3, 4, 5 };
auto iter = a.erase(a.cbegin() + 1, a.cend() - 1);
std::cout << "element pointed to by returned value: " << *iter << '\n';
for (auto i : a)
{
std::cout << i << '\n';
}
}
{
Vector<int> a = { 1, 2, 3, 4, 5 };
auto iter = a.erase(a.cbegin() + 1);
std::cout << "element pointed to by returned value: " << *iter << '\n';
for (auto i : a)
{
std::cout << i << '\n';
}
}
}
注意:成員函數中的循環可以替換為采用迭代器的std::move
的重載。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.