【问题标题】:Initializing function array with function template使用函数模板初始化函数数组
【发布时间】:2012-04-23 01:06:51
【问题描述】:

我目前正在尝试使用模板元编程实现一些功能,如下所示

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>;

我的意图是通过类型的整数索引实现类型的动态调度机制。

似乎可以通过使用可变参数模板机制(C++/C++11 - Switch statement for variadic templates?)来实现,但目前我无法使用支持可变参数模板的编译器。

所以我尝试通过使用类型列表(在现代 C++ 设计中)和模板递归作为概念代码来解决,如下所示。

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];
};

当然,上面的代码不会被正确编译。如何实现此功能?

【问题讨论】:

  • 你的伪代码真的很奇怪。什么是cell?当你打电话给init(tail())时,你在做什么?你怎么称呼这个init成员函数?
  • @fontanini:summerlight 正在尝试使用来自 Andrei Alexandrescu 的 Modern C++ Design 的一种称为“类型列表”的技术
  • @fontanini:类型列表基本上是一种类似于列表的编译时数据结构,每个元素都是一个类型。 cell 类似于链表的 cons 单元格。 init() 成员函数递归地处理类型列表的元素。在type_dispatch的构造函数中调用。
  • 哦,我现在明白了。我没听说过这种技术。谢谢!

标签: c++ template-meta-programming


【解决方案1】:

您的代码修复了一些错误并填写了缺失的部分,对我来说编译得很好:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    相关资源
    最近更新 更多