C++ 如何在不知道类型的情况下声明模板指针?

C++ 如何在不知道类型的情况下声明模板指针?,c++,templates,generics,pointers,C++,Templates,Generics,Pointers,这就是我想做的: ExampleTemplate* pointer_to_template; cin >> number; switch (number) { case 1: pointer_to_template = new ExampleTemplate<int>(); break; case 2: pointer_to_template = new ExampleTemplate<double>(); break; } p

这就是我想做的:

ExampleTemplate* pointer_to_template;
cin >> number;
switch (number) {
case 1:
    pointer_to_template = new ExampleTemplate<int>();
    break;
case 2:
    pointer_to_template = new ExampleTemplate<double>();
    break;
}
pointer_to_template->doStuff();
ExampleTemplate*指向模板的指针;
cin>>数量;
开关(编号){
案例1:
指向模板的指针=新示例模板();
打破
案例2:
指向模板的指针=新示例模板();
打破
}
指向模板->doStuff()的指针;

这不会编译,因为在声明指针时必须指定模板类型。(
ExampleTemplate*pointer\u to_template
应该是
ExampleTemplate*pointer\u to_template
)不幸的是,在开关块中声明之前,我不知道模板的类型。在这种情况下,什么是最好的解决方法?

您试图做的是不可能的。这是因为您的
ExampleTemplate
类本身并不存在,仅当您将其与类型关联时才存在

您可以使用继承获得该行为:

  • 定义一个
    GeneralExampleTemplate
    (不是模板类)
  • 使
    examplemplate
    继承自
    GeneralExampleTemplate
  • 这样,您就可以创建一个
    GeneralExampleTemplate
    指针,并用一个(例如)
    exampletplate
    来分配它

  • 你不能
    ExampleTemplate
    ExampleTemplate
    是两种不同的、不相关的类型。如果您总是可以切换多个选项,请改用
    boost::variant

    typedef boost::variant<Example<int>, Example<double>> ExampleVariant;
    ExampleVariant v;
    switch (number) {
        case 1: v = Example<int>(); break;
        case 2: v = Example<double>(); break;
    }
    // here you need a visitor, see Boost.Variant docs for an example
    

    通过让模板类派生自常规类,可以执行类似的操作:

    #include<iostream>
    #include<sstream>
    using namespace std;
    
    class ExampleBase{
    
    public:
        virtual ~ExampleBase() {}
        virtual string Get() = 0;
    };
    
    template<typename T>
    class ExampleTemplate : public ExampleBase{
    
    private:
        T data;
    
    public:
        ExampleTemplate(T t) : data(t){}
    
        string Get(){        
            stringstream s; s << data;
            return s.str();
        }
    
    };
    
    int main(){
    
        ExampleBase *base;
        int number;
        cout << "> " << flush; cin >> number;
    
        switch(number){
            case 1:
                base = new ExampleTemplate<int>(42);
                break;
            case 2:
                base = new ExampleTemplate<double>(3.14);
                break;
            default:
                return 1;
        }
    
        cout << base->Get() << endl;
    
        delete base;
        return 0;
    }
    
    #包括
    #包括
    使用名称空间std;
    类示例库{
    公众:
    虚拟~ExampleBase(){}
    虚拟字符串Get()=0;
    };
    模板
    类ExampleTemplate:公共ExampleBase{
    私人:
    T数据;
    公众:
    示例模板(T):数据(T){
    字符串Get(){
    弦的数目;
    开关(编号){
    案例1:
    base=新的示例模板(42);
    打破
    案例2:
    base=新的示例模板(3.14);
    打破
    违约:
    返回1;
    }
    
    得不到听起来您需要运行时多态性,即虚拟函数。模板是关于静态多态性的,即编译时已知的类型。让我重新表述:
    boost
    ?对于starter@julio.alegria当前位置不是。这完全取决于所讨论的新手。有些人不会有什么麻烦,其他人可能会超出他们的深度。OP会决定跟进这个问题,或提出问题,或忽略这个答案,因为他/她更容易理解。但最好是提出“正确的方法”来做这类事情,并向新程序员介绍好的库(并让他们思考这些库)当我们接近软件问题时,@ Julo.AleGria:以什么方式?它只是更多的C++黑箱。@ GMan,我认为把C++作为半动态的类型化编程语言(至少不是初学者)是不好的,这可能会导致可怕的编程错误。
    #include<iostream>
    #include<sstream>
    using namespace std;
    
    class ExampleBase{
    
    public:
        virtual ~ExampleBase() {}
        virtual string Get() = 0;
    };
    
    template<typename T>
    class ExampleTemplate : public ExampleBase{
    
    private:
        T data;
    
    public:
        ExampleTemplate(T t) : data(t){}
    
        string Get(){        
            stringstream s; s << data;
            return s.str();
        }
    
    };
    
    int main(){
    
        ExampleBase *base;
        int number;
        cout << "> " << flush; cin >> number;
    
        switch(number){
            case 1:
                base = new ExampleTemplate<int>(42);
                break;
            case 2:
                base = new ExampleTemplate<double>(3.14);
                break;
            default:
                return 1;
        }
    
        cout << base->Get() << endl;
    
        delete base;
        return 0;
    }