英文:
Metaprogram to use enumerator value as template parameter of a template function at runtime
问题
我想编写一个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?
英文:
Let't suppose I have this code:
// 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;
}
I would like to write a bar
function that specializes foo
for each element of my_enum
, and that calls, at run-time, one of those functions based on the value of an argument of bar
. The simplest solution is to write a switch and manually adding all the cases:
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>();
}
}
with some additional tricks to handle a unexpected value adding a default value of the switch. Unfortunately, for very long enumerators this solution brings to very long and redundant code, that is difficult to be maintained.
Is there any metaprogramming solution to simplify this code, for example using Boost Hana or Boost MPL?
答案1
得分: 1
Here's the translated code portion:
如果枚举值如您的示例一样从零开始且连续... 给定以下助手函数:
template <std::size_t ... Is>
std::array<int(*)(void), sizeof...(Is)>
getFuncArray (std::index_sequence<Is...>)
{ return {{ &foo<static_cast<my_enum>(Is)>... }}; }
您可以在 bar()
中添加一个静态函数数组,并根据输入调用正确的函数。
我的意思是:
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)]();
}
英文:
If the enum values are, as in your example, starting from zero and consecutive... given an helper function as follows
template <std::size_t ... Is>
std::array<int(*)(void), sizeof...(Is)>
getFuncArray (std::index_sequence<Is...>)
{ return {{ &foo<static_cast<my_enum>(Is)>... }}; }
you can add, in bar()
, a static
array of functions and call the correct one according the input.
I mean
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)]();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论