Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
775 views
in Technique[技术] by (71.8m points)

templates - C++ Call functions based on enum values

I have this code

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() {};

Based on the value of heuristic I want to call a specific function in select(). I don't know the value of heuristic at compile time, as it depends on user input. To avoid the conditional check in select() I would like to use templates. How can I accomplish this?

question from:https://stackoverflow.com/questions/65903259/c-call-functions-based-on-enum-values

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

To avoid the conditional check in select() [...]

A simple way to avoid all conditional checks (hidden or otherwise) in select() could be to create an array of pointers to your functions. You then look the function up by using its current Heuristic value (which must start at 0 and not have any gaps). If the Heuristic value changes rarely, you can even move the lookup out of select() completely.

Example:

##include <iostream>

void selectONE() { std::cout << "one
"; };
void selectTWO() { std::cout << "two
"; };
void selectTHREE() { std::cout << "three
"; };

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"
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...