在成员数据中使用模板参数的模板 class 的基 class 指针

Base class pointer for a template class that uses template parameter in member data

对于以下模板class

template <class T> class Arbitrary {
protected:
    vector<T> ObjectArray;
public:
    Arbitrary(){}   
};

我希望能够有一个基向量 class 指针,我知道我需要使用一个接口 class 但我无法让它工作,任何建议都是非常感谢。

[..] I want to eventually write vector<Arbitrary*> name;

Arbitrary 是模板,不是类型。要从它 "obtain" 一个类型,你需要 "apply" 它到另一个类型(比如 int)。这给你 Arbitrary<int> 作为 "result" 类型。这个过程称为模板实例化

如果您想要一个包含可能已从模板 Arbitrary 实例化的任何可能类型的对象的向量,则需要为它们提供一个通用类型(这样每个对象 "is a" 对象那种常见的类型)。这是因为 std::vector 只存储单一类型的对象。

要使对象 "behave"(在具有某种类型的意义上)不同,即使它们 "have" 是常见类型,您需要使它们(或者更确切地说是它们的常见类型)多态。这是通过给通用类型一些 virtual 函数来完成的。 (并且由于你想 delete/destruct 通过公共类型公开的 "interface" 对象,你 需要 使析构函数成为虚拟的!)

struct ArbitraryBase {
  // Add "common interface" functions here, as virtual
  virtual ~ArbitraryBase() = 0; // pure virtual to avoid creating objects
};
inline ArbitraryBase​::~ArbitraryBase() {}

template<typename T>
struct Arbitrary : ArbitraryBase {
  // whatever
};

现在,要真正能够使用该多态性 属性 而不会成为 对象切片 的受害者,您需要使用引用或指针语义:

std::vector<ArbitraryBase *> objects;

如果 objects 向量应该拥有对象的所有权,则您应该考虑像 std::unique_ptr<ArbitraryBase> 这样的智能指针,而不是原始指针,或者如果对象的生命周期是 std::reference_wrapper<ArbitraryBase> =38=]可靠地 由其他东西处理。

但是,如果您不在 ArbitraryBase 中添加任何公共接口(更多虚拟成员函数),那么您基本上是在重新发明 std::any / boost::any。所以最好改用那些经过良好测试的实现。