从 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;
}
使用 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;
}