How can I declare a template pointer without knowing the type?
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:
- Define a
GeneralExampleTemplate
(not a template class). - Make
ExampleTemplate<T>
inherit fromGeneralExampleTemplate
. - That way you can create a
GeneralExampleTemplate
pointer and assign it with a (for example)ExampleTemplate<int>
.
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, 2022Comments
-
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 beExampleTemplate<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 over 12 years
boost
? isn't it a little bit complicated for a starter? -
juliomalegria over 12 yearslet me rephrase:
boost
? it is a little bit complicated for a starter -
Cat Plus Plus over 12 years@julio.alegria: No, it's not.
-
Mordachai over 12 yearsIt 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 over 12 years@julio.alegria: In what way? It's just more C++ black boxes.
-
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.