2

I'm currently trying to implement some functionality as below with template metaprogramming

typedef void (*function)(void*);
function function_array[/* total size of type list */];

...

template<typename T>
void some_func(void*)
{
    // do something with type T
}

...

function_array[0] = &some_func<type_0>;
function_array[1] = &some_func<type_1>;
function_array[2] = &some_func<type_2>;

...

function_array[n] = &some_func<type_n>;

My intention is to implement dynamic dispatch mechanism for type by integer index of type.

It seems that it can be achieved by using variadic template mechanism ( C++/C++11 - Switch statement for variadic templates? ), but currently I can't use a compiler that supports variadic template.

So I've tried to workaround via using type list (in the modern C++ design) and template recursion as a conceptual code like below.

template<typename list, typename function>
struct type_dispatch
{
    type_dispatch() { init(); }

    template<typename typelist>
    void init();

    template<typename head, typename tail>
    void init(cell<head, tail>&)
    {
        // setting dispatch array with templated function
        function_array[index_of<list, head>::value] = &function<head>;
        init(tail());
    }
    void init(null&) {}

    // functor array which size is equal to the size of type list    
    function function_array[size_of<list>::value];
};

Of course, above code won't be compiled properly. How can I implement this functionality?

Community
  • 1
  • 1
summerlight
  • 882
  • 7
  • 16
  • Your pseudo code is really weird. What is a `cell`? What are you doing when you call `init(tail())`? How would you call this `init` member function? – mfontanini Apr 23 '12 at 01:41
  • @fontanini: summerlight is trying to use a technique known as "typelists" from Andrei Alexandrescu's *Modern C++ Design* – HighCommander4 Apr 23 '12 at 01:49
  • @fontanini: Typelists are basically a compile-time data structure resembling a list, with each element being a type. A `cell` is the analogue of a cons cell for a linked list. The `init()` member function processes the elements of the typelist recursively. It is called in the constructor of `type_dispatch`. – HighCommander4 Apr 23 '12 at 01:56
  • Ohh I get it now. I hadn't heard of this technique. Thanks! – mfontanini Apr 23 '12 at 02:07

1 Answers1

1

Your code, with a few mistakes fixed and the missing pieces filled in, compiles just fine for me:

struct null {};

template <typename head, typename tail>
struct cell {};

template <typename, typename>
struct index_of;

template <typename head, typename tail>
struct index_of<cell<head, tail>, head>
{
    static const int value = 0;
};

template <typename head, typename tail, typename other>
struct index_of<cell<head, tail>, other>
{
    static const int value = 1 + index_of<tail, other>::value;
};

template <typename>
struct size_of;

template <>
struct size_of<null>
{
    static const int value = 0;
};

template <typename head, typename tail>
struct size_of<cell<head, tail> >
{
    static const int value = 1 + size_of<tail>::value;
};

template <typename T>
void the_function(void*)
{
}

template<typename list, typename function_t>
struct type_dispatch
{
    type_dispatch() { init(list()); }

    template<typename head, typename tail>
    void init(cell<head, tail>)
    {
        // setting dispatch array with templated function
        function_array[index_of<list, head>::value] = &the_function<head>;
        init(tail());
    }

    void init(null) {}

    // functor array which size is equal to the size of type list    
    function_t function_array[size_of<list>::value];
};

typedef void (*function_t)(void*);

int main()
{
    type_dispatch<cell<int, cell<float, cell<double, null> > >, function_t> t;
}
HighCommander4
  • 50,428
  • 24
  • 122
  • 194