在运行时使用枚举值作为模板函数的模板参数的元程序

Metaprogram to use enumerator value as template parameter of a template function at runtime

假设我有这个代码:

// the enumerator
enum class my_enum {
    ONE,
    TWO,
    THREE
};

// the function
template <my_enum E>
int foo() {
    return 0;
}

// a specialization
template<>
int foo<my_enum::TWO>() {
    return 1;
}

我想编写一个 bar 函数专门针对 my_enum 的每个元素 foo,并在 运行 时调用其中一个基于参数 bar 的值的函数。最简单的解决方案是写一个开关并手动添加所有情况:

int bar(my_enum value) {
    switch (value) {
    using m = my_enum;
    case m::ONE:
        return foo<m::ONE>();
    case my_enum::TWO:
        return foo<m::TWO>();
    case my_enum::THREE:
        return foo<m::THREE>();
    }
}

使用一些额外的技巧来处理意外值,添加开关的默认值。不幸的是,对于非常长的枚举器,此解决方案会带来非常长且冗余的代码,难以维护。

是否有任何元编程解决方案来简化此代码,例如使用 Boost Hana 或 Boost MPL?

如果枚举值,如您的示例所示,从零开始连续...给出如下辅助函数

template <std::size_t ... Is>
std::array<int(*)(void), sizeof...(Is)>
    getFuncArray (std::index_sequence<Is...>)
 { return {{ &foo<static_cast<my_enum>(Is)>... }}; }

您可以在 bar() 中添加一个 static 函数数组,并根据输入调用正确的函数。

我是说

int bar (my_enum value)
 {
   static auto const arrF
      = getFuncArray(std::make_index_sequence<
                        1u+static_cast<std::size_t>(my_enum::THREE)>{});

   return arrF[static_cast<std::size_t>(value)]();
 }