繁体   English   中英

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

[英]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()中的条件检查,我想使用模板。 我怎样才能做到这一点?

由于它取决于运行时值,因此无法摆脱某种运行时检查。 您可以使用ifswitch …… 或者像std::mapstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM