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

16,375

Solution 1

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;

Solution 2

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;
}

Solution 3

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>.
Share:
16,375
Nathan
Author by

Nathan

GitHub profile: https://github.com/osidenate LinkedIn: https://www.linkedin.com/pub/nathan-nelson/1b/878/744 Website: http://websocks.net E-Mail: [email protected]

Updated on June 15, 2022

Comments

  • Nathan
    Nathan almost 2 years

    This is what I would like to do:

    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();
    

    This doesn't compile because the template type must be specified when declaring the pointer. (ExampleTemplate* pointer_to_template should be ExampleTemplate<int>* pointer_to_template.) Unfortunately, I don't know the type of the template until it's declared in the switch block. What is the best work around for this situation?

  • juliomalegria
    juliomalegria over 12 years
    boost? isn't it a little bit complicated for a starter?
  • juliomalegria
    juliomalegria over 12 years
    let me rephrase: boost? it is a little bit complicated for a starter
  • Cat Plus Plus
    Cat Plus Plus over 12 years
    @julio.alegria: No, it's not.
  • Mordachai
    Mordachai over 12 years
    It entirely depends on the newbie in question. Some people will have little trouble, others would be out of their depth. The OP will decide to follow up on this, or ask questions, or ignore this answer for something he/she understands more readily. But it's good to present "the right way" to do this sort of thing, and to introduce new programmers to good libraries (and get them thinking about such libraries) when approaching software problems.
  • GManNickG
    GManNickG over 12 years
    @julio.alegria: In what way? It's just more C++ black boxes.
  • juliomalegria
    juliomalegria over 12 years
    @GMan, I think it isn't a good idea to show C++ as a semi-dynamic typing programming language (at least not for a starter), this could lead to terrible programming mistakes.