从 C++11 中的列表中选择并评估一个函数

Choose and evaluate a function from a list in C++11

使用 C++,我需要从列表中选择一个函数,然后使用一些输入对该函数求值。我知道足够危险,我已经通过一些魔法解决了我的问题,但我对我的解决方案有疑问。这是一个最小的工作示例:

double foo(double x) {return x+2;}
double bar(double x) {return x*7;}
double baz(double x) {return x-1;}

int main() {

  double x = 3;
  auto func_list = {foo,bar,baz};

  // This is chosen from an external source, 
  // setting to a fixed value for the example 
  int random_choice = 1;

  double y = (*(func_list.begin()+random_choice))(x);

  return 0;
}

问题:这是从列表中选择一个函数并对其求值的正确方法吗? auto这是一把双刃剑,它创造了东西,但我不知道它是什么类型。

[auto] created something, but I don't know what type it is.

将花括号列表(相同类型)分配给 auto 时,例如:

auto func_list = {foo,bar,baz};

列表将始终转换为 std::initializer_list。那是你的自动变量的类型。

Is this the right way?

从那里开始,您剩下的代码是有效的。它是否正确的方式将永远取决于你。

首先,

auto func_list = {foo,bar,baz};

创建一个 std::initializer_list<double (*)(double)> 类型的变量。虽然您的工作有效,但最好使用更符合预期的容器:

std::vector<double(*)(double)> func_list = {foo, bar, baz};

无论哪种方式,您都可以编写一个 random_select 函数,例如:

template <typenme Iter>
auto random_select(Iter begin, Iter end) -> decltype(*begin)
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, std::distance(begin, end) - 1);
    return *std::next(begin, dis(gen));
}

template <typename C>
auto random_select(const C& cont) -> decltype(*cont.begin()) {
    return random_select(cont.begin(), cont.end());
}

double y = random_select(func_list)(x);

你说,

auto here was a double-edged sword, it created something, but I don't know what type it is.

您可以创建一个函数指针数组并使用该数组,如果这对您来说更简单的话。喜欢:

double foo(double x) {return x+2;}
double bar(double x) {return x*7;}
double baz(double x) {return x-1;}

int main() {

   double x = 3;

   // Use the compiler to get a type that can be used to define an array.
   typedef decltype((&foo)) function_type;

   // Define an array of function pointers.
   function_type func_list[] = {foo, bar, baz};

   // Now use the array to call one of the functions.    
   int random_choice = 1;
   double y = func_list[random_choice](x);

   return 0;
}

如果您不想使用编译器魔法,您可以使用:

int main() {

   double x = 3;

   // Define a function type using typedef
   typedef double (*function_type)(double);

   // Define an array of function pointers.
   function_type func_list[] = {foo, bar, baz};

   // Now use the array to call one of the functions.    
   int random_choice = 1;
   double y = func_list[random_choice](x);

   return 0;
}