是否可以将带有捕获和参数的 lambda 传递给另一个函数?如果是这样,如何?
Is it possible to pass a lambda with a capture and parameters to another function? If so, how?
我正在尝试创建一个通用输入验证函数(在 C++17 中),它可以接受一个函数指针,该函数指针是一个布尔值,用于测试输入是否有效。例如,如果我希望用户输入一个小于 6 的值,则 lambda 的主体将为 return input < 6
.
问题出在我正在尝试做的事情上。我正在制作一个简单的控制台游戏以更加熟悉 C++。我有一个名为 Change_Weapon 的函数,它接收用户拥有的所有武器的向量。由此,以下 lambda 产生:
// Variables renamed for clarity
auto validation_func = [&owned_weapon_vec](unsigned input_to_test) -> bool
{
return input_to_test > 0 && input_to_test <= owned_weapon_vec.size();
};
// Function call to input validation function
auto weapNum = valid_input<unsigned>(validation_func);
这是我的输入验证函数的样子。
template<typename Ty>
Ty valid_input(std::function<bool(Ty)>(valid_input_function))
{
Ty input_val;
bool first_loop = true;
do
{ // Input value validiation loop
if (first_loop) first_loop = false;
else
{
std::cout << "Invalid entry value. Please re-enter: ";
std::cin.clear();
std::cin.ignore(/* Max possible value of long long */, '\n');
}
while (!(std::cin >> input_val))
{ // Input type validation loop
std::cout << "Invalid entry type. Please re-enter: ";
std::cin.clear();
std::cin.ignore(/* Max val of long long*/, '\n');
}
} while (!valid_input_function(input_val))
}
一些注意事项:
- 被传递的函数将始终接受 input_val 作为参数,这将是它唯一的参数
- 传递的函数总是return一个布尔值
- 被传递的函数应该能够是一个匿名的 lambda(或者至少是一个命名的 lambda)
我试过其他各种帖子,但似乎找不到一个讨论 lambda 捕获 和 都有参数的答案。目前,Resharper 告诉我:
No viable function
Argument types: '<lambda>'.
Candidates considered:
unsigned valid_input<unsigned>(std::function<bool(unsigned)> valid_input_function)
conversion of 1st argument 'validation_func' is ill-formed: cannot convert lvalue of
type '<lambda>' to parameter type 'std::function::<bool(unsigned)>'
如何调用 valid_input
函数?对我来说,它可以像这样工作:
template<typename T>
T valid_input(std::function<bool(T)> predicate)
{
T some_input(69); // I do not know where do you want to take it from
std::cout << "predicate returns: " << predicate(some_input) << std::endl;
return some_input;
}
int main()
{
size_t some_threshold(0);
size_t result = valid_input<size_t>([some_threshold](size_t input) -> bool
{
std::cout << "predicate invoked with " << input << std::endl;
return input > some_threshold;
});
std::cout << result << std::endl;
}
或者,如果您不想显式使用 valid_input
的模板参数,您可以首先显式地将 lambda 分配给 std::function
:
std::function<bool(size_t)> f = [some_threshold](size_t input)
{
std::cout << "predicate invoked with " << input << std::endl;
return input > some_threshold;
};
size_t result = valid_input(f);
我正在尝试创建一个通用输入验证函数(在 C++17 中),它可以接受一个函数指针,该函数指针是一个布尔值,用于测试输入是否有效。例如,如果我希望用户输入一个小于 6 的值,则 lambda 的主体将为 return input < 6
.
问题出在我正在尝试做的事情上。我正在制作一个简单的控制台游戏以更加熟悉 C++。我有一个名为 Change_Weapon 的函数,它接收用户拥有的所有武器的向量。由此,以下 lambda 产生:
// Variables renamed for clarity
auto validation_func = [&owned_weapon_vec](unsigned input_to_test) -> bool
{
return input_to_test > 0 && input_to_test <= owned_weapon_vec.size();
};
// Function call to input validation function
auto weapNum = valid_input<unsigned>(validation_func);
这是我的输入验证函数的样子。
template<typename Ty>
Ty valid_input(std::function<bool(Ty)>(valid_input_function))
{
Ty input_val;
bool first_loop = true;
do
{ // Input value validiation loop
if (first_loop) first_loop = false;
else
{
std::cout << "Invalid entry value. Please re-enter: ";
std::cin.clear();
std::cin.ignore(/* Max possible value of long long */, '\n');
}
while (!(std::cin >> input_val))
{ // Input type validation loop
std::cout << "Invalid entry type. Please re-enter: ";
std::cin.clear();
std::cin.ignore(/* Max val of long long*/, '\n');
}
} while (!valid_input_function(input_val))
}
一些注意事项:
- 被传递的函数将始终接受 input_val 作为参数,这将是它唯一的参数
- 传递的函数总是return一个布尔值
- 被传递的函数应该能够是一个匿名的 lambda(或者至少是一个命名的 lambda)
我试过其他各种帖子,但似乎找不到一个讨论 lambda 捕获 和 都有参数的答案。目前,Resharper 告诉我:
No viable function
Argument types: '<lambda>'.
Candidates considered:
unsigned valid_input<unsigned>(std::function<bool(unsigned)> valid_input_function)
conversion of 1st argument 'validation_func' is ill-formed: cannot convert lvalue of
type '<lambda>' to parameter type 'std::function::<bool(unsigned)>'
如何调用 valid_input
函数?对我来说,它可以像这样工作:
template<typename T>
T valid_input(std::function<bool(T)> predicate)
{
T some_input(69); // I do not know where do you want to take it from
std::cout << "predicate returns: " << predicate(some_input) << std::endl;
return some_input;
}
int main()
{
size_t some_threshold(0);
size_t result = valid_input<size_t>([some_threshold](size_t input) -> bool
{
std::cout << "predicate invoked with " << input << std::endl;
return input > some_threshold;
});
std::cout << result << std::endl;
}
或者,如果您不想显式使用 valid_input
的模板参数,您可以首先显式地将 lambda 分配给 std::function
:
std::function<bool(size_t)> f = [some_threshold](size_t input)
{
std::cout << "predicate invoked with " << input << std::endl;
return input > some_threshold;
};
size_t result = valid_input(f);