简体   繁体   English

我是否正确使用了函数指针?

[英]Am I using function pointers correctly?

I have a function that looks something like this in pseudocode: 我有一个伪代码看起来像这样的函数:

std::string option = "option1" // one of n options, user supplied

for (int i = 0; i < 100000; i++) {

    if (option == "option1") {
        doFunction1a();
    } else if (option == "option2") {
        doFunction2a();
    } else if (option == "option3") {
        doFunction3a();
    }

    //  more code...

    if (option == "option1") {
        doFunction1b();
    } else if (option == "option2") {
        doFunction2b();
    } else if (option == "option3") {
        doFunction3b();
    }

}

However, I could avoid the repeated if statement inside the loop by doing something like this: 但是,通过执行以下操作,可以避免在循环内重复执行if语句:

std::string option = "option1" // one of n options, user supplied

int (*doFunctiona)(int, int);
int (*doFunctionb)(int, int);

if (option == "option1") {
    doFunctiona = doFunction1a;
    doFunctionb = doFunction1b;
} else if (option == "option2") {
    doFunctiona = doFunction2a;
    doFunctionb = doFunction2b;
} else if (option == "option3") {
    doFunctiona = doFunction3a;
    doFunctionb = doFunction3b;
}

for (int i = 0; i < 100000; i++) {

    doFunctiona();

    //  more code...

    doFunctionb();

}

I realize that this will have little effect on performance (the time spend by the functions dominates the time it takes to execute the if statement). 我意识到这对性能几乎没有影响(函数所花费的时间主导着执行if语句所花费的时间)。

However, In terms of "good coding practices", is this a good way to set up variable function calling? 但是,就“良好的编码习惯”而言,这是设置变量函数调用的好方法吗? With "good" I mean: (1) easily expandable, there could easily be 20 options in the future; 所谓“好”,是指:(1)易于扩展,将来很可能会有20种选择; 2) results in readable code. 2)产生可读的代码。 I'm hoping there exists some kind of standard method for accomplishing this. 我希望有某种标准的方法可以完成此任务。 If not, feel free to close as opinion based. 如果没有,请根据意见随时结束。

Just use an unordered_map and spare yourself the if-else-if-orgy: 只需使用unordered_map并保留if-else-if-orgy即可:

std::unordered_map<std::string, std::vector<int (*)(int, int)>> functions;
functions.insert({ "option1", { doFunction1a, doFunction1b } });
...
const auto& vec = functions["option1"];
for(auto& f : vec) f(1, 2);

Beside using map I recommend to use std::function and lambdas which will give you more flexibility and syntax is more friendly (at least for me): 除了使用map之外,我建议使用std::function和lambdas,它们将为您提供更大的灵活性,并且语法更加友好(至少对我而言):

std::unordered_map<std::string, std::function<void()>> functions {
    {
        "option1", 
        [] { 
            functionA();
            functionB();
        }
    },
    {
        "option2", 
        [] { 
            functionC();
            functionD();
        }
    }
};

auto optionFuncIt = functions.find("option1");
if (optionFuncIt != functions.end()) {
     optionFuncIt->second();
} else {
     std::cerr << "Invalid option name" << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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