通过在C++中切换,在运行时选择模板实例化

Joe*_*oel 5 c++

我有一组由整数类型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; }
};
Run Code Online (Sandbox Code Playgroud)

这用于在程序的运行时使用switch语句选择一个特定的索引(这应该会产生一个高效的查找表).该开关独立于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;
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,这很好用,但是这个类Foo并不是我想要应用这个开关的唯一类.事实上,我有很多类都是由相同的整数类型模板化的.所以我想barSwitch用"Foo"函数"模板" 上面的类,这样我就可以插入不同的类或不同的函数.我能想到的唯一方法是使用宏:

#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; \
  }\
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的,更多的C++风格的方式这样做?

Ker*_* SB 7

模板模板参数是关键:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

template <Index I> struct Foo
{
    template <typename T> static void bar(const T & x);
};

barSwitch<Foo>(1, Blue);
Run Code Online (Sandbox Code Playgroud)

(当然,您有责任确保您替换的每个可能的模板Switcher都有成员模板bar.如果没有,您将收到编译错误.)