我有这个密码
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()中调用一个特定的函数。我不知道heuristic在编译时的值,因为它取决于用户的输入。为了避免select()中的条件检查,我想使用模板。我怎样才能做到这一点?
发布于 2021-01-26 14:54:32
以避免
select()中的有条件检查.
避免select()中所有条件检查(隐藏或其他)的一个简单方法是创建指向函数的指针数组。然后使用其当前的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"
}发布于 2021-01-26 14:48:34
由于它依赖于运行时值,因此无法摆脱某种类型的运行时检查。这要么是由你用if,switch,…来完成的或者由像std::map,std::unordered_map这样的容器
因此,您所关心的应该是可读性和可维护性。
我想--就像在注释中已经建议的那样--使用switch而不是if,但不是因为编译器可以更好地优化它(IMHO编译器将能够为两者生成相同的代码),而是允许静态分析器警告您不要使用枚举。
如果问题是关于性能问题,那么这应该是一个问题,只有当你调用这些函数在一个高频率。因此,如果是这样的话,您可以为任务创建一个基于模板的入口点,然后根据用户选择将函数作为模板参数传递给它:
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() {};发布于 2021-01-26 14:35:17
定义一个map<Heuristic, lambdas>,其中lambdas被定义为void并且不接受任何参数
void f()然后接受用户输入,并获取输入键的值,并触发lambda。
https://stackoverflow.com/questions/65903259
复制相似问题