Question

I am trying to create a templatized vector, where the template type is determined by runtime parameters. I am aware that template stuff is completed before runtime, basically I am trying to funnel runtime input into a select few previously selected compile-time types. Here's a high level example of what I'd like to be able to do.

for (int i = 0; i < 2; ++i)
{
    std::vector<getRunTimeT(i)> v;

    // Do stuff with v
}

So, the vector should be initialized with a type selected by the runtime input.

So far, I've come to the conclusion that specialized template meta-programming is needed, and I have functionality that does what I need with compile-time parameters:

template<int i>
struct getCompileTimeT
{
    typedef int type; // Base case, not expected to occur.
};

template<>
struct getCompileTimeT<0>
{
    typedef int type;
};

template<>
struct getCompileTimeT<1>
{
    typedef float type;
};

So I can do this:

std::vector<getCompileTimeT(1)> type; // Creates a vector of floats

So, somehow I need to bridge the compile-time aspect with some function that selects the correct type from the predefined template types. Here is an (illegal) example of how I envision this bridging function to work:

// Illegal demonstrative desired functionality
_type_ getRunTimeT(int select)
{
    if (select == 0) return getCompileTimeT<0>;
    else if (select == 1) return getCompileTimeT<1>;
}

So basically I am looking for something that 'bridges' between the compile-time functionality and the run-time functionality I've spoken of. Is this possible?

Thanks for any help you can give!

EDIT: Additional info:

Thank you for the solutions thus far; they have been very useful in helping me to understand this more thoroughly. I would like to provide an API-type function where a user can manipulate or use a type, which is 'dynamic' from their perspective. For example:

UserClass::function()
{
    for (int i = 0; i < 2; ++i)
    {
        // getType() is something that may be a template parameter
        myFunc<getType(i)>();
    }
}

template<class T>
void UserClass::myFunc()
{
    std::vector<T> v;

    // Now the user has a vector to play with in their member function.
}
Was it helpful?

Solution

try this

template <class T>
void do_stuff()
{
    std::vector<T> v;
    // Do stuff with v
}

void do_suff_dispatch(int i)
{
    switch (i)
    {
        case 0:
            do_stuff<int>();
            break;
        case 1:
            do_stuff<float>();
            break;
    }
}

for (int i = 0; i < 2; ++i)
{
    do_suff_dispatch(i);
}

OTHER TIPS

You can consider using boost::variant<> as a type preserving generic value store:

http://www.boost.org/doc/libs/1_55_0/doc/html/variant/tutorial.html

The idea goes as following:

typedef boost::variant<
    getCompileTimeT<0>,
    getCompileTimeT<1>
> variant_type;

variant_type getRunTimeT(int select)
{
    if (select == 0) return variant_type(getCompileTimeT<0>());
    else if (select == 1) return variant_type(getCompileTimeT<1>());
}

At this stage, you can rely on variant's visitor pattern (described in variant's tutorial) to do type safe value dispatch down the line.

Depending on your application and with a bit of template magic (especially on c++11) you can define the original variant type concisely over range of getCompileTimeT<> template parameters (so no need to enumerate all explicitly).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top