簡體   English   中英

我如何在 c++ 中實現 vector 的擦除(迭代器擦除(首先是 const_iterator,最后是 const_iterator))

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM