我有一个重载功能,具有以下签名:
void Foo(const std::function<void(int )> &func);
void Foo(const std::function<void(int, int)> &func);
当我想用lambdas使用Foo()时,我必须做这样的事情:
Foo((std::function<void(int )>) [] (int i ) { /* do something */ });
Foo((std::function<void(int, int)>) [] (int i, int j) { /* do something */ });
两者都不是那么用户友好。使用该功能更容易,而无需添加铸件&#34;(std :: function&lt; ...&gt;)&#34;在lambdas之前 - 像这样:
Foo([] (int i ) { /* do something */ }); // executes the 1st Foo()
Foo([] (int i, int j) { /* do something */ }); // executes the 2nd Foo()
所以,我需要另一个重载,接受lambda作为其参数,并自动将lambda转换为上述签名之一。如何才能做到这一点?或者,首先可能吗?
template <typename Function> void Foo(Function function) {
// insert code here: should be something like
// - check the signature of the 'function'; and
// - call 'Foo()' corresponding to the signature
}
请帮忙。
PS。我正在使用VS2010。
答案 0 :(得分:3)
如果你的lambda没有捕获任何变量 - 也就是说,它以[]
开头 - 那么它可以转换为函数指针,你可以像这样声明Foo
:
void Foo(void(*func)(int));
void Foo(void(*func)(int, int));
如果您想保留std::function
版本,可以将这些版本转发到该版本。如果您不想单独实现它们,我认为可变参数模板可以很好地实现:
template<class... Args>
void Foo(void(*func)(Args...)) {
return std::function<void(Args...)>(func);
}
如果你的lambdas捕获变量,那么它们就不能转换为函数指针,你需要自己将它们包装在std::function
中。
答案 1 :(得分:1)
Lambda转换为std :: function&lt;&gt;隐含地,没有明确的转换需要。
std::function<void(int, int)> func = [](int a, int b){ printf("Hello Lambda world!"); };
func(1, 2);
啊,你正试图获得一个const引用。为什么呢?你应该更好地使用右手参考(因为它是临时的)或副本。在这两种情况下,它也应该隐式转换......