How can I declare a template pointer without knowing the type?

后端 未结 3 1419
孤城傲影
孤城傲影 2021-02-01 19:27

This is what I would like to do:

ExampleTemplate* pointer_to_template;
cin >> number;
switch (number) {
case 1:
    pointer_to_template = new ExampleTempla         


        
相关标签:
3条回答
  • 2021-02-01 20:12

    You can't. ExampleTemplate<int> and ExampleTemplate<double> are two different, unrelated types. If you always have a switch over several options, use boost::variant instead.

    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
    

    Another way is to use an ordinary base class with virtual public interface, but I'd prefer variant.

    struct BaseExample {
        virtual void do_stuff() = 0;
        virtual ~BaseExample() {}
    };
    
    template <typename T>
    struct Example : BaseExample { ... };
    
    // ..
    BaseExample *obj;
    
    0 讨论(0)
  • 2021-02-01 20:16

    What you're trying to do is not possible. This is becase your ExampleTemplate class doesn't exist by itself, only exists when you relate it with a type.

    You could get that behaviour using inheritance:

    1. Define a GeneralExampleTemplate (not a template class).
    2. Make ExampleTemplate<T> inherit from GeneralExampleTemplate.
    3. That way you can create a GeneralExampleTemplate pointer and assign it with a (for example) ExampleTemplate<int>.
    0 讨论(0)
  • 2021-02-01 20:18

    You can do something similar by having your template class derive from a regular class:

    #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;
    }
    
    0 讨论(0)
提交回复
热议问题