[英]Choosing a template instantiation at runtime though switch in C++
I have a set of functions that are templated both by an integer type Index
and a class type T
, that I "partially specialize" in the following manner: 我有一组由整数类型Index
和类类型T
模板化的函数,我以下列方式“部分地专门化”:
// Integer type
enum Index{One,Two,Three,Four};
// Default implementation
template<int I>
struct Foo{
template<typename T> static void bar(const T& x){ std::cout <<"default" << endl; }
};
// Template specializations
template<>
struct Foo<One>{
template<typename T> static void bar(const T& x){ std::cout << "one" << endl; }
};
This I use to select a particular index at the runtime of the program using a switch-statement (which should result in an efficient look-up table). 这用于在程序的运行时使用switch语句选择一个特定的索引(这应该会产生一个高效的查找表)。 The switch is independent of T
: 该开关独立于T
:
template<typename T>
void barSwitch(int k, const T& x){
switch(k){
case ONE: Foo<ONE>::bar(x); break;
case TWO: Foo<TWO>::bar(x); break;
case THREE: Foo<THREE>::bar(x); break;
}
}
This works fine, of course, but the class Foo
is not the only class for which I would like to apply the switch. 当然,这很好用,但是Foo
类并不是我想要应用这个开关的唯一类。 In fact, I have a lot of classes that are all templated by the same integer type. 事实上,我有很多类都是由相同的整数类型模板化的。 So I would like to "template" the class barSwitch
above with the function "Foo" as well, so that I can plug in a different class or a different function. 所以我想用“Foo”函数“模板”上面的类barSwitch
,这样我就可以插入不同的类或不同的函数。 The only way I can think of to achieve this is to use a macro: 我能想到的唯一方法是使用宏:
#define createBarSwitch(f,b) \
template<typename T> \
void barSwitch(int k, const T& x){ \
switch(k){ \
case ONE: f<ONE>::b(x); break; \
case TWO: f<TWO>::b(x); break; \
case THREE: f<THREE>::b(x); break; \
}\
}
Is there some better, more C++ style way of doing this? 有没有更好的,更多的C ++风格的方式这样做?
Template template parameters are the key: 模板模板参数是关键:
enum Index { One, Two, Three, Four };
template <template <Index> class Switcher, typename T>
void barSwitch(int k, const T & x)
{
switch (k)
{
case 1: Switcher<One>::template bar<T>(x); break;
case 2: Switcher<Two>::template bar<T>(x); break;
default: assert(false);
}
}
Usage: 用法:
template <Index I> struct Foo
{
template <typename T> static void bar(const T & x);
};
barSwitch<Foo>(1, Blue);
(It is your responsibility to ensure that every possible template that you substitute for Switcher
has a member template bar
, of course. If not, you'll get a compile error.) (当然,您有责任确保替换Switcher
每个可能模板都有成员模板bar
。如果没有,您将收到编译错误。)
template<template<int> class F>
struct BarFunc {};
template<>
struct BarFunc<Foo> {
template<Index I, typename T>
static void call(const T& x) {
Foo<I>::bar(x);
}
};
template<template<int> class F, typename T>
void barSwitch(int k, const T& x) {
switch(k){
case One: BarFunc<F>::call<One>(x); break;
case Two: BarFunc<F>::call<Two>(x); break;
case Three: BarFunc<F>::call<Three>(x); break;
}
}
You can parametrize which function you want to call by providing a BarFunc specialization. 您可以通过提供BarFunc特化来参数化要调用的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.