gpt4 book ai didi

c++ - 使用类型名递归实例化模板?

转载 作者:行者123 更新时间:2023-11-30 03:32:31 24 4
gpt4 key购买 nike

对于采用整数的模板化函数,我编写了以下通用调度程序:

#define Dispatch_Template(funct_name, max) \
template<int i> decltype(&funct_name<0>) Dispatch_template_##funct_name (int index) { \
return (index == i) ? funct_name <i> : Dispatch_template_##funct_name <i - 1>(index); \
} \
template<> decltype(&funct_name<0>) Dispatch_template_##funct_name <-1>(int) { \
return nullptr; \
} \
decltype(&funct_name<0>) Dispatch_##funct_name (int i) { \
return Dispatch_template_##funct_name <max>(i); \
} \

这行得通,我可以做这样的事情:

template<int some_int> void PrintInt() {
printf("int is %i\n", some_int);
}

Dispatch_Template(PrintInt, 6);

int main()
{
for (int i = 0; i < 6; ++i) {
Dispatch_PrintInt(i)();
}
return 0;
}

但是如果我想将类型名称参数传递给我的模板函数怎么办?

例如,假设它看起来像这样:

template<int some_int, typename some_type> void PrintSomeType(some_type arg) {
// do something
}

我希望能够做到这一点:

template<typename some_type> void caller(some_type arg) {
Dispatch_Template(PrintSomeType, some_type, 6);
for (int i = 0; i < 6; ++i) {
Dispatch_PrintSomeType(i)(arg);
}
}

我不确定该怎么做 - 我遇到了“此处不允许模板声明”的问题。 (注意这里的 Dispatch_Template 必须在函数内部,因为函数本身是模板化的。)

最佳答案

您无法让声明在函数内部工作,因为 block 范围内不允许使用模板。这是一条死胡同。

因此您需要一种在函数外部声明它的方法。

事实证明,宏是邪恶的,只需将宏重写为模板即可使一切正常运行。

#include <utility>
#include <assert.h>
#include <iostream>

template<template<int, typename...> class func, typename... Ts>
class Dispatcher {
public:
using function_ptr = decltype(&func<0, Ts...>::call);

template<int max=10>
static function_ptr get_func(int i) {
assert(i>=0 && i<max);
return get_func_impl(i, std::make_integer_sequence<int, max>());
}

private:
template<int... vals>
static function_ptr get_func_impl(int i, std::integer_sequence<int, vals...> ) {
static constexpr function_ptr funcs[] = {&func<vals, Ts...>::call...};
return funcs[i];
}

};

template <int i, typename T>
struct Foo {
static void call(T val) {
std::cout << "Hello foo " << i << " " << val << std::endl;
}
};

int main() {
Dispatcher<Foo, double>::get_func<>(5)(2.3); // output: Hello foo 5 2.3
}

最后一步是为所需的 template <...> struct X { call(); }; 创建一个宏格式。这是必需的,因为您不能将模板函数传递到模板中。

注意:std::integer_sequence 仅适用于 c++14,但您可以添加一个 polyfill 实现,例如来自 here .尝试在没有它的情况下实现嵌套的部分专用结构会很困惑,因为您无法在模板内专门化函数。

关于c++ - 使用类型名递归实例化模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43413196/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com