模板指针,而不知道类型

Template pointer without knowing the type

本文关键字:不知道 类型 指针      更新时间:2023-10-16
template <typename T>
class Container
{
    private:
    T data;
    public:
    Container(T newData) : data(newData) {}
    T getData() {return data;}
};

int main()
{
    Container* numContainer=new Container<int>(5);
    //Do something with numContainer
    delete numContainer;
}

这不能编译,因为必须指定Container指针的类型,例如int
这可以,正如我在一些快速搜索后发现的那样,通过创建一个不是模板的ContainerBase类来处理,并让Container从中派生。让指针为ContainerBase类型将不允许我使用getData()等方法,因为它返回类型T,因此不能在ContainerBase类中声明。

我能以某种方式有一个指针,可以指向任何类型的模板类的实例,即使类包含方法,如在上面的例子?

我可以有一个指针,可以指向任何类型的模板类的实例,即使类包含方法,如在上面的例子?

不,你不能,为了实例化template class,编译器必须知道T的类型。将类模板看作是类的蓝图,而不是类的具体定义。对于你为模板类指定的每种类型(例如,Container<int>),编译器都会生成一个单独的定义。当编译器看到你的模板类的名字(例如,Container)时,它不能凭空推断出它的类型。

恕我直言,为了避免每次都显式地指定模板的类型,你能做的最好的事情就是使用别名,就像下面的例子一样:

template <typename T>
class Container {
  T data;
public:
  Container(T const &newData) : data(newData) {}
  T getData() const {return data;}
};
using iContainer = Container<int>;
int main() {
    iContainer* numContainer=new iContainer(5);
    //Do something with numContainer
    delete numContainer;
}

或者使用运行时多态性,就像你已经提到的,结合使用dynamic_cast,就像下面的例子:

class BaseContainer {
public:
    virtual ~BaseContainer() {}
};
template <typename T>
class Container : public BaseContainer {
  T data;
public:
  Container(T const &newData) : data(newData) {}
  T getData() const {return data;}
};
int main() {
  BaseContainer *numContainer = new Container<int>(5);
  Container<int> *ptr = dynamic_cast<Container<int>*>(numContainer);
  if(ptr) std::cout << ptr->getData() << std::endl;;
  delete numContainer;
}

现场演示