簡體   English   中英

使用模板時如何從std :: vector刪除元素?

[英]How to erase an element from std::vector when using templates?

我有一個相當簡單的模板化類,其中將項目存儲在向量中。 但是,當我嘗試擦除一個元素時,出現以下錯誤:

C2678: binary '==': no operator found which takes a left-hand operand of type
      'TestComponent' (or there is no acceptable conversion)

這是我正在使用的代碼:

#pragma once
#include <vector>

template<class T>
class ComponentManager {
    ComponentManager() {};
    ~ComponentManager() {};

    T* newComponent() {
        components.emplace_back(T());
        return &components.back();
    }

    // This is the method I'm having trouble with
    void destroyComponent(T* t) {
        components.erase(std::remove(components.begin(), components.end(), *t), components.end());
    }

private:
    std::vector<T> components;
};

是的,我知道這會導致無效的指針等。 沒必要去那里。

如果您嘗試通過指針擦除,則需要為此使用正確的算法。 std::remove在元素之間進行相等性比較。 根據您的評論,您不需要這樣做,因此您可能更喜歡std::remove_if

void destroyComponent(T* t) {
    components.erase(
        std::remove_if(components.begin(), components.end(), [t](const T& comp) {
            return &comp == t;
        }),
        components.end()
    );
}

請注意,將指針保留在vector並不是特別安全,因為插入向量中可能會導致重新分配,這會使所有先前保留的指針失效。 您可能需要考慮使用其他容器(或者只具有vector<T*> ,甚至更好的是vector<unique_ptr<T>> )。

std::remove搜索由開始和結束迭代器定義的給定序列,以查找指定為第三個參數的給定值。 顯然,該值的類型必須實現相等比較運算符,以便std::remove將序列中的值與給定值進行比較。

如錯誤消息所示,您的TestComponent類未實現==運算符。

首先,您的解決方案很危險:看起來您將存儲在std::vector的對象的指針保留在內部,除非事先預留足夠的空間,否則在添加新元素時將獲得懸空的指針。 如果您保留了足夠的空間,則可能應該通過指針而不是按值刪除對象:

components.erase(std::remove_if(components.begin(), components.end(), [t]( const T &tc ) { return &tc == t; } ), components.end());

除非您可以按值唯一地標識對象,然后需要為該類實現適當的operator==

我建議將TestComponentstd::unique_ptr存儲在一起,然后通過std::vector進行內存重新分配就不會有問題,並且刪除操作將按預期工作,而無需實現operator==

template<class T>
class ComponentManager {
    ComponentManager() {};
    ~ComponentManager() {};

     template< class... Args >
     T *newComponent( Args...&& args ) {
        components.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
        return components.back().get();
    }

    // This is the method I'm having trouble with
    void destroyComponent(T* t) {
        components.erase(std::remove(components.begin(), components.end(), t), components.end());
    }

private:
    std::vector<std::unique_ptr<T>>> components;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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