[英]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==
。
我建議將TestComponent
與std::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.