[英]C++ Call functions based on enum values
我有这个代码
class Foo {
private:
enum class Heuristic {
ONE,
TWO,
THREE
};
Heuristic h;
void select();
};
void Foo::select() {
if (h == Heuristic::ONE)
selectONE();
else if (h == Heuristic::TWO)
selectTWO();
else
selectTHREE();
}
void selectONE() {};
void selectTWO() {};
void selectTHREE() {};
基于heuristic
的值,我想在select()
中调用特定的 function 。 我不知道heuristic
在编译时的价值,因为它取决于用户输入。 为了避免select()
中的条件检查,我想使用模板。 我怎样才能做到这一点?
由于它取决于运行时值,因此无法摆脱某种运行时检查。 您可以使用if
、 switch
…… 或者像std::map
、 std::unordered_map
这样的容器来完成这些操作
因此,您关心的应该是可读性和可维护性。
我想 - 就像评论中已经建议的那样 - 使用switch
而不是if
,但不是因为编译器可以更好地优化它(恕我直言,编译器将能够为两者生成相同的代码),而是允许 static 分析器警告你关于未使用的枚举。
如果问题是关于性能问题,那么只有在高频调用这些函数时才会出现问题。 因此,如果是这种情况,您可以为您的任务创建一个基于模板的入口点,根据用户选择将 function 作为模板参数传递给该入口点:
template<auto SelectedHeuristic>
void Foo::task() {
for( /* … */ ) {
SelectedHeuristic();
}
}
void Foo::select() {
switch(h) {
case Heuristic::ONE:
Foo::task<selectONE>();
break;
case Heuristic::TWO:
Foo::task<selectTWO>();
break;
case Heuristic::THREE:
Foo::task<selectTHREE>();
break;
}
}
void selectONE() {};
void selectTWO() {};
void selectTHREE() {};
为了避免
select()
中的条件检查 [...]
在select()
中避免所有条件检查(隐藏或其他)的一种简单方法是创建一个指向函数的指针数组。 然后,您使用 function 的当前Heuristic
值(必须从 0 开始并且没有任何间隙)向上查看。 如果Heuristic
值很少更改,您甚至可以将查找完全移出select()
。
例子:
##include <iostream>
void selectONE() { std::cout << "one\n"; };
void selectTWO() { std::cout << "two\n"; };
void selectTHREE() { std::cout << "three\n"; };
using func_ptr_t = void(*)(); // the signature of your functions
class Foo {
public:
enum class Heuristic {
ONE,
TWO,
THREE
};
void set_heuristic(Heuristic); // a function to do the lookup
void select();
private:
Heuristic h;
func_ptr_t current_func; // a pointer to the selected function
};
void Foo::set_heuristic(Heuristic value) {
// a simple map from Heuristic value to function pointer
static const func_ptr_t funcmap[] = {
&selectONE,
&selectTWO,
&selectTHREE,
};
h = value; // perhaps not needed?
// look up the function pointer based on "h"
current_func = funcmap[static_cast<unsigned>(h)];
}
void Foo::select() {
// a pretty fast callsite:
current_func();
}
int main() {
Foo bar;
bar.set_heuristic(Foo::Heuristic::ONE);
bar.select(); // prints "one"
}
定义一个map<Heuristic, lambdas>
其中 lambdas 被定义为 void 并且不带参数
void f()
然后获取用户输入并获取该输入键的值并触发 lambda
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.