c++ - 元程序在运行时使用枚举值作为模板函数的模板参数
问题描述
假设我有这个代码:
// 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
专门foo
针对 的每个元素的函数my_enum
,并在运行时根据 的参数的值调用其中一个函数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)]();
}
推荐阅读
- c - 我的 sscanf 如果卡在无限循环中,我该如何解决
- homebrew - Homebrew 安装特定版本的公式
- javascript - 如何使用 rxjs observables 制作异步协同程序?
- vb.net - 来自 format.com 的进度信息
- php - phpmailer 附件到多个邮件
- bash - bash脚本为if测试编写一行快捷方式
- typescript - 打字稿没有检测到非法参数
- ecmascript-6 - 使用其他解构值的对象解构默认值
- objective-c - iPhone X 系列上的 UIBezierPath 弧和矩形问题,但在早期的手机上没有
- maven - 打开 exectuable-jar 时出现 JNI 错误,然后是 Java 错误