首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于枚举值的C++调用函数

基于枚举值的C++调用函数
EN

Stack Overflow用户
提问于 2021-01-26 14:31:09
回答 3查看 497关注 0票数 1

我有这个密码

代码语言:javascript
复制
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()中的条件检查,我想使用模板。我怎样才能做到这一点?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-01-26 14:54:32

以避免select()中的有条件检查.

避免select()中所有条件检查(隐藏或其他)的一个简单方法是创建指向函数的指针数组。然后使用其当前的Heuristic值查找函数(该值必须从0开始,不存在任何间隙)。如果Heuristic值很少更改,甚至可以将查找完全移出select()

示例:

代码语言:javascript
复制
##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"
}
票数 2
EN

Stack Overflow用户

发布于 2021-01-26 14:48:34

由于它依赖于运行时值,因此无法摆脱某种类型的运行时检查。这要么是由你用ifswitch,…来完成的或者由像std::mapstd::unordered_map这样的容器

因此,您所关心的应该是可读性和可维护性。

我想--就像在注释中已经建议的那样--使用switch而不是if,但不是因为编译器可以更好地优化它(IMHO编译器将能够为两者生成相同的代码),而是允许静态分析器警告您不要使用枚举。

如果问题是关于性能问题,那么这应该是一个问题,只有当你调用这些函数在一个高频率。因此,如果是这样的话,您可以为任务创建一个基于模板的入口点,然后根据用户选择将函数作为模板参数传递给它:

代码语言:javascript
复制
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() {};
票数 4
EN

Stack Overflow用户

发布于 2021-01-26 14:35:17

定义一个map<Heuristic, lambdas>,其中lambdas被定义为void并且不接受任何参数

代码语言:javascript
复制
void f()

然后接受用户输入,并获取输入键的值,并触发lambda。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65903259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档