考虑以下玩具示例:
#include <iostream>
template <typename T>
void foo(T func, int *i) {
if (i) {
func(*i);
} else {
func();
}
}
int main() {
auto n = new int{2};
foo([](int x) { std::cout << x << std::endl; }, n);
foo([]() { std::cout << "Foo" << std::endl; }, nullptr);
return 0;
}
我想创建一个函数,它接收具有不同签名的 lambda 函数并在其范围内调用它们。如果我不在 foo
中调用 lambda 函数,它编译得很好,但如果我调用它,代码就不会编译。
有没有办法接收具有不同签名的 lambda 并在函数中调用它?
最佳答案
在您的函数模板中,T
必须被确定为一种特定类型,并在整个实例化过程中保持该类型。
但是,您可以通过使 foo
成为可变参数模板并将参数包传递给传入的 lambda 来完成您想要的:
#include <iostream>
template <typename T, typename ...Args>
void foo(T func, Args... args) {
func(std::forward<Args>(args)...);
}
int main() {
auto n = new int{ 2 };
foo([](int x) { std::cout << x << std::endl; }, n[0]);
foo([]() { std::cout << "Foo" << std::endl; });
foo([](int a, int b) { std::cout << a + b << "\n"; }, 3, 2);
}
这样 foo
只需要包含一个 func
的调用,它在每个实例化过程中都有一个一致的类型——但可以从一个实例化到下一个实例化。
在这种情况下,当您传递的函数不带任何参数时,您不会为参数传递特殊值。如果它不接受参数,您就不会传递参数。
关于c++ - 将具有不同签名的 lambda 传递给泛型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49547439/