Mat
Mat

Reputation: 11893

Is it possible to choose a C++ generic type parameter at runtime?

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

Answers (5)

UncleBens
UncleBens

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

Matt Joiner
Matt Joiner

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

Charles Salvia
Charles Salvia

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

Mike Dinescu
Mike Dinescu

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

ephemient
ephemient

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

Related Questions