我有一个好主意,可以(对我而言)简化很多事情。
假设您有一个函数,它接受一个带有 x 个参数的函数,如果事件发生,该函数将被执行。为了简化这一点,您使用 typedef 定义了一个新类型,即函数指针。
typedef void (*HandlerFunction)(...);
void setHandler(HandlerFunction fun) {...}
现在您使用 setHandler 函数来...使用带有额外特定参数的 lambda 函数设置处理程序,因为您知道将始终使用这些特定参数调用此函数。
setHandler([](int i, std::string arg) {
std::cout << "Event with i=" << i << " and arg=" << arg << "!" << std::endl;
});
现在的问题是……这在 C++ 中是否可行?如果可行,如何实现?
最佳答案
可变参数
我想通了,如何使用可变参数列表来做到这一点。诀窍是在可变函数周围使用包装器并使用 va_copy
:
#include <iostream>
#include <functional>
#include <cstdarg>
std::function<void (int, va_list)> foo = [] (int numargs, va_list args)
{
va_list args_copy;
va_copy(args_copy, args);
std::cout << "Old Foo " <<va_arg(args_copy,int) << std::endl;
va_end(args_copy);
};
void set_foo(std::function<void (int, va_list)> new_foo)
{
foo = new_foo;
}
void wrapper(int numargs, ...)
{
va_list args;
va_start(args, numargs);
foo(numargs, args);
va_end(args);
}
int main() {
wrapper(123,456);
set_foo([](int numargs, va_list args)
{
va_list args_copy;
va_copy(args_copy, args);
std::cout << "New Foo " << va_arg(args_copy,int) << std::endl;
va_end(args_copy);
});
wrapper(123,456);
return 0;
}
这导致:
Old Foo 456
New Foo 456
I don't why the wrapper is needed, maybe someone knows. But it works :P
已知参数
您可以使用 initializer_list
将特定类型的可变参数传递给变量 lambda。
#include <iostream>
#include <functional>
#include <initializer_list>
std::function<void (std::initializer_list<int>)> foo = [](std::initializer_list<int> args)
{
for (auto i: args) std::cout << "Old Foo: "<< i << '\n';
};
void setFoo(std::function<void (std::initializer_list<int>)> new_foo) {
foo = new_foo;
};
int main()
{
foo({2, 4, 5});
std::cout << std::endl;
setFoo([](std::initializer_list<int> args)
{
for (auto i: args) std::cout << "New Foo: "<< i << '\n';
});
foo({2, 4});
}
这将返回:
Old Foo: 2
Old Foo: 4
Old Foo: 5
New Foo: 2
New Foo: 4
关于c++ - 如何组合 lambda、可变参数函数和函数指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51968880/