强制模板成员函数实例化

时间:2015-11-28 22:05:19

标签: c++ templates c++11 instantiation

我在命名空间N中有一个C类,公共模板成员函数F如下:

namespace N {
    class C {
    public:
        template<int I>
        void F() {
            // ...
        }
    };
};

I的{​​{1}}值在运行时才知道。但是,N::C::F<I>的值受限制为I。我正在寻找一种方法来强制此功能将模板扩展为所有256种可能的形式。

到目前为止,我在0 <= I < 2^8的第二个函数中手动创建了一个静态数组,指向每个可能的函数:

C

虽然我想知道是否有更好的方法。我已经在 template<int I> void F() { // ... } void G(int I) { static void(* const funcs[256])() = { F<0>, F<1>, F<2>, ... }; funcs[I](); } 中有一个宏,它负责为N的每个值构建一个单独的结构(供F本身使用),并且正在查看是否可以集成模板成员函数的实例化不知何故:

I

我提出的方法不能正常工作,编译器抱怨F不是constexpr。 F操纵 template<int> struct S; #define M(I, n) \ template<> struct S<I> { \ static const char name[] = #n; \ /* Some how instantiate the function here, like (just guessing here): static const SEvaluator<I> eval = &C::F<I>; given template<int I> using SEvaluator = void(*)(); */ }; M(0, "foo"); M(1, "bar"); #undef M 的几个变量并调用外部方法,不能声明为constexpr。有没有办法挽救这个或者我必须采用我的第一个hackish方法?

2 个答案:

答案 0 :(得分:4)

您可以使用index_sequence<I...>(C ++ 14)并将I展开到静态数组中。

template<std::size_t... Is>
void G(int i, std::index_sequence<Is...>) {
    using C = void(C::*)();
    static C funcs[sizeof...(Is)] = { &C::F<Is>... };
    (this->*funcs[i])();
}

void G(int i) {
    G(i, std::make_index_sequence<256>());
}

对于非C ++ 14解决方案,您可以编写自己的index_sequence版本:

template<int... Is>
struct index_sequence { };

template<int N, int... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> { };

template<int... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> { };

答案 1 :(得分:2)

显然我被蝙蝠侠击败了。无论如何我会发布这个:原则是一样的,它只是以另一种方式完成。

template <std::size_t... Idx>
auto const &makeFunctions(std::index_sequence<Idx...>) {
    static auto funcs = {&N::C::F<Idx>...};
    return funcs;
}

auto const &function(std::size_t i) { return *(begin(makeFunctions(std::make_index_sequence<256>{})) + i); }

致电:

N::C c;
for(int i = 0; i < 10; ++i)
    (c.*function(i))();

Live on Coliru