C++ 使用模板时如何从std::vector中删除元素?
我有一个非常简单的模板类,其中我将项目存储在向量中。但是,当我尝试擦除某个元素时,会出现以下错误:C++ 使用模板时如何从std::vector中删除元素?,c++,templates,vector,C++,Templates,Vector,我有一个非常简单的模板类,其中我将项目存储在向量中。但是,当我尝试擦除某个元素时,会出现以下错误: 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<
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;
};
#pragma一次
#包括
模板
类组件管理器{
ComponentManager(){};
~ComponentManager(){};
T*newComponent(){
组件。向后放置(T());
返回&components.back();
}
//这是我遇到麻烦的方法
空心构件(T*T){
擦除(std::remove(components.begin()、components.end()、*t)、components.end());
}
私人:
std::向量分量;
};
是的,我知道这会导致指针失效等等。无需执行此操作。
std::remove
在给定序列中搜索指定为第三个参数的给定值,该序列由起始迭代器和结束迭代器定义。显然,值的类型必须实现相等比较运算符,以便std::remove
将序列中的值与给定值进行比较
您的
TestComponent
类没有实现=
操作符,正如错误消息所说。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());
除非您可以通过值唯一地标识对象,然后需要为该类实现适当的操作符==
我建议使用std::unique\u ptr
存储TestComponent
,这样您就不会出现通过std::vector
重新分配内存的问题,并且您的删除操作将按预期进行,而无需实现运算符==
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;
};
模板
类组件管理器{
ComponentManager(){};
~ComponentManager(){};
模板<类…参数>
T*newComponent(参数…&&Args){
组件。向后放置(std::使_唯一(std::向前(args)…);
返回组件.back().get();
}
//这是我遇到麻烦的方法
空心构件(T*T){
擦除(std::remove(components.begin()、components.end()、t)、components.end());
}
私人:
std::vector>分量;
};
首先,您的解决方案是危险的:看起来您保留了存储在std::vector
中的对象指针,除非您提前预留足够的空间,否则在添加新元素时,您将得到一个悬空的指针。如果您预留了足够的空间,您可能应该按指针而不是按值删除对象:
components.erase(std::remove_if(components.begin(), components.end(), [t]( const T &tc ) { return &tc == t; } ), components.end());
除非您可以通过值唯一地标识对象,然后需要为该类实现适当的操作符==
我建议使用std::unique\u ptr
存储TestComponent
,这样您就不会出现通过std::vector
重新分配内存的问题,并且您的删除操作将按预期进行,而无需实现运算符==
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;
};
模板
类组件管理器{
ComponentManager(){};
~ComponentManager(){};
模板<类…参数>
T*newComponent(参数…&&Args){
组件。向后放置(std::使_唯一(std::向前(args)…);
返回组件.back().get();
}
//这是我遇到麻烦的方法
空心构件(T*T){
擦除(std::remove(components.begin()、components.end()、t)、components.end());
}
私人:
std::vector>分量;
};
是否定义了TestComponent
运算符==
。我想尽量不需要它,因为泛型类型可以是任何类型。我可能只是制定了错误的删除方法。与手头的问题无关,你不必写emplace\u back(t())
,你只需写emplace\u back()
@manabreak就可以删除你需要检查它们是否相等的东西。如果要提供比较两个对象的方法,则需要使用remove\u。为什么要使用原始指针而不是引用