基于标志运行两个不同的函数

Run two different functions based on flags?

本文关键字:两个 函数 运行 于标志 标志      更新时间:2023-10-16

我正在编写一个程序,用户可以在其中设置选项标志。

我的问题是我想根据用户标志调用函数的不同版本,并且我不想每次选择要调用的版本时都if(flag),因为我必须在我处理的每一行上检查if()语句。

这是一个学校项目,所以我试图找到最有效的方法来确定我想调用哪个函数, and I read if()' 语句在这里很昂贵。

那么有没有办法在开头基本上说

if(flag)
  // use this function the rest of the program
else
  // use this other function for the rest of the program

因此,如果有一种方法可以在开始时说if(flag)使用此函数,则程序的其余部分将其他函数用于程序的其余部分

只需执行以下操作:

void func1() {
    // ...
}
void func2() {
    // ...
}
int main(int argc, char* argv[]) {
    std::function<void()> func;
    // Make your decision once:
    if(std::string(argv[1]) == "func1") {
        func = func1;
    }
    else if(std::string(argv[1]) == "func2") {
        func = func2;
    }
    // Call func many times
    func();
    // ...
}

您可以使用旧样式的函数指针数组,如下所示:

#include <stdio.h>
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
typedef enum{
    SUM=0,
    SUB,
    MUL,
    DIV
}FLAG;
int main(void)
{
  int result;
  int i, j, op;
  p[SUM] = sum; /* address of sum() */
  p[SUB] = subtract; /* address of subtract() */
  p[MUL] = mul; /* address of mul() */
  p[DIV] = div; /* address of div() */
  printf("Enter two numbers: ");
  scanf("%d %d", &i, &j);
  printf("0: Add, 1: Subtract, 2: Multiply, 3: Dividen");
  do {
    printf("Enter number of operation: ");
    scanf("%d", &op);
  } while(op<0 || op>3);
  result = (*p[op]) (i, j);
  printf("%d", result);
  return 0;
}
int sum(int a, int b)
{
  return a + b;
}
int subtract(int a, int b)
{
  return a - b;
}
int mul(int a, int b)
{
  return a * b;
}
int div(int a, int b)
{
  if(b) 
      return a / b;
  else 
      return 0;
}

做这种事情的最好方法是使用模板。您的问题可以理解为类似于"环路拉出"问题:

void foo(vector v, bool b) {
    for (auto e : v) {
        // do stuff
        if (b) // stuff
        else // other stuff
        // do more stuff
    }
}

分支在循环过程中不会改变,但我们一直在点击它。优雅地重写它非常困难,特别是如果分支前后有一堆代码。使用模板,我们可以使用这种方法:

template <bool b>
void foo(vector<double>& v) {
    for (auto e : v) {
        // do stuff
        if (b) // stuff
        else // other stuff
        // do more stuff
    }
}
void foo(vector<double>& v, bool b) {
    if (b) foo<true>(v);
    else foo<false>(v);
}

在内部编译器将生成两个版本的foo,一个版本的布尔值在编译时被硬编码为true,另一个在编译时被硬编码为false。在每种情况下,编译器都可以毫无问题地完全消除分支。然后,您只需在调用开始时调度到正确的函数,仅分支一次。但是代码的结构完全相同;您只需添加几行代码,这些代码不会随着循环变得更大而增加。