我正在尝试编写一个处理 ObjArray 向量的容器,它是一个模板类。 ObjArray 继承自基类,容器包含一个基指针列表,我在操作时将其转换为正确的类型。如何使呼叫者尽可能安全?
下面的代码片段显示了我正在尝试对可能出错的注释执行的操作。
#include <iostream>
#include <vector>
#include <memory>
struct CustomA{
int a;
};
struct CustomB{
float b;
};
class IObjArray{
public:
virtual void RemoveObj(int obj_id) = 0;
virtual ~IObjArray() = default;
};
template<typename T>
class ObjArray : public IObjArray{
public:
void RemoveObj(int obj_id) override {
std::cout << "Removing object of id" << obj_id << "\n";
// Mechanism for removing object from vector below...
}
void AddT(T obj){
vec_of_T_.push_back(obj);
}
private:
std::vector<T> vec_of_T_;
};
class ObjManager{
public:
template<typename obj>
size_t RegisterObj(){
list_.emplace_back(std::make_unique<ObjArray<obj>>());
return list_.size() - 1;
}
template<typename T>
void AddObj(size_t obj_array_id, T obj){
static_cast<ObjArray<T>*>(list_[obj_array_id].get())->AddT(obj);
}
private:
std::vector<std::unique_ptr<IObjArray>> list_;
};
int main()
{
ObjManager om;
auto id_a = om.RegisterObj<CustomA>();
auto id_b = om.RegisterObj<CustomB>();
CustomA a{0};
om.AddObj(id_a, a);
om.AddObj(id_b, a); // This compiles but is bad. Anyway to stop this happening? Registering a CustomA type in a CustomB ObjArray.
// om.AddObj<CustomB>(id_b, a); // This doesn't compile because of type mismatch
return 0;
我可以在注册对象时使用某种形式的 typeid(T) 添加到映射中,然后每当调用 AddObj 时,它都可以将 typeid(T) 作为键键入映射中并拉出正确的 ObjArray。我宁愿使用基于 ID 的系统来索引数组并尽可能快地保持索引。我也无法将方法 AddObj 添加到 IObjArray 接口,因为它们是模板化的。
是否可以解决这些问题,还是让呼叫者意识到这一点很重要?
谢谢!
如果
id_a
和 id_b
可以是不同的类型,您可以将 size_t
索引包装到用元素类型标记的类模板中:
template <typename T>
struct Index {
size_t value = 0;
using type = T;
};
class ObjManager{
public:
template<typename obj>
Index<obj> RegisterObj(){
list_.emplace_back(std::make_unique<ObjArray<obj>>());
return {list_.size() - 1};
}
template<typename T>
void AddObj(Index<T> obj_array_id, T obj){
static_cast<ObjArray<T>*>(list_[obj_array_id.value].get())->AddT(obj);
}
private:
std::vector<std::unique_ptr<IObjArray>> list_;
};
然后这里:
om.AddObj(id_a, a);
om.AddObj(id_b, a);
第一行编译,而第二行则不编译,因为
Index
的 id_b
类型与 b
的类型不匹配。