Reputation: 11893
Is there a way to choose the generic type of a class at runtime or is this a compile-time thing in C++?
What I want to do is something like this (pseudocode):
Generictype type;
if(somveval==1)
type = Integer;
if(someval==2)
type = String;
list<type> myList;
Is this possible in C++? and if yes, how?
Upvotes: 10
Views: 10080
Reputation: 41351
It is possible with Boost.Variant (fixed number of different types) or Boost.Any (a type that can store any type, basically your "void pointer" but with type information).
It is also possible if String and Integer happened to be derived from a polymorphic base class. (But for that they would have to implement the same interface, which may or may not be possible in your case.)
Generally, polymorphism is the easiest way to do it, and this is indeed used all the time.
Variant and Any take quite a bit of work to be used: you still need somehow to obtain the contents as the right type they are storing. (Sort of as if you were to use down-casts to derived classes, instead of relying on polymorphic method calls.)
Upvotes: 2
Reputation: 118600
The closest you'll get is:
template <typename T>
void do_stuff_with_list
{
list<T> myList;
...
}
enum Type
{
Integer = 1,
String
};
void do_stuff(Type type)
{
switch (type)
{
case Integer:
do_stuff_with_list<int>();
break;
case String:
do_stuff_with_list<string>();
break;
};
}
Upvotes: 0
Reputation: 53319
It's a compile time thing. Template parameter types must be known to the compiler at compile-time.
That being, said, using certain template meta-programming techniques, you can choose one type or another AT compile-time, but only if all possible types are known at compile-time, and only if the condition for selecting a type can be resolved at compile time.
For example, using partial specialization you could select a type at compile time based on an integer:
template <typename T>
class Foo
{ };
template <int N>
struct select_type;
template<>
struct select_type<1>
{
typedef int type;
};
template<>
struct select_type<2>
{
typedef float type;
};
int main()
{
Foo<select_type<1>::type> f1; // will give you Foo<int>
Foo<select_type<2>::type> f2; // will give you Foo<float>
}
Upvotes: 13
Reputation: 55750
As others have also responded, the answer to your question is "No", C++ doesn't support dynamic typing at run-time. I just wanted to point out that depending on what you're trying to accomplish, you may be able to simulate this dynamic typing using a union, which is how the VARIANT type is implemented in COM.
Upvotes: 2
Reputation: 204926
I can't think of a situation where this would be useful, but…
#include "boost/variant.hpp"
#include <list>
#include <string>
boost::variant<std::list<int>, std::list<std::string> >
unknown(int someval) {
if (someval == 1)
return boost::variant<std::list<int>, std::list<std::string> >(
std::list<int>());
else if (someval == 2)
return boost::variant<std::list<int>, std::list<std::string> >(
std::list<std::string>());
}
Upvotes: 0