我试图使用一个lambda代替一个函数指针,但VS2010似乎不能转换它.我试过使用这样的std ::函数,它崩溃,我不知道如果我这样做正确!
#include <windows.h> #include <conio.h> #include <functional> #include <iostream> #include <concrt.h> void main() { std::function<void(void*)> f = [](void*) -> void { std::cout << "Hello\n"; }; Concurrency::CurrentScheduler::ScheduleTask(f.target<void(void*)>(),0); getch(); }
对我来说似乎很奇怪,编译器无法将这样的lambda转换为简单的函数指针,因为它没有捕获任何变量 – 在这种情况下,我不知道可以做什么.
每个lambda的类型是否唯一?所以我可以使用lambdas的类型作为模板参数来使用模板函数来生成一个可以被调用的唯一静态函数,并希望优化出来?
更新
以下似乎是有效的,但它是否安全?
#include <windows.h> #include <conio.h> #include <iostream> #include <concrt.h> template<typename Signature> struct Bind { static Signature method; static void Call(void* parameter) { method(parameter); } }; template<typename Signature> Signature Bind<Signature>::method; template<typename Signature> void ScheduleTask(Signature method) { Bind<Signature>::method = method; Concurrency::CurrentScheduler::ScheduleTask(&Bind<Signature>::Call,0); } void main() { ScheduleTask ( [](void*) { std::cout << "Hello"; } ); ScheduleTask ( [](void*) { std::cout << " there!\n"; } ); getch(); }
再次更新
所以有了帮助,我已经提出了更短的:
template<typename Signature> void (*LambdaBind(Signature))(void*) { struct Detail { static void Bind(void* parameter) { Signature method; method(parameter); } }; return &Detail::Bind; }
这可以用来包装一个没有void(*)(void *)的关闭的lambda到等效的函数指针中.看来在以后版本的VS2010中这将变得不必要.
那么如何让这个工作的lambda与闭包?
再次更新
在VS2010关闭的工作 – 不知道如果它是’安全’虽然…
template<typename Signature> struct Detail2 { static std::function<void(void*)> method; static void Bind(void* parameter) { method(parameter); } }; template<typename Signature> std::function<void(void*)> Detail2<Signature>::method; template<typename Signature> void (*LambdaBind2(Signature method))(void*) { Detail2<Signature>::method = method; return &Detail2<Signature>::Bind; }
解决方法
This feature of lambda’s was added after VS2010 implemented them,so they don’t exist in it yet.
这是一个可能的通用解决方法,非常未经测试:
#include <functional> #include <iostream> namespace detail { // helper specializations,// define forwarding methods template <typename Lambda,typename Func> struct lambda_wrapper; #define DEFINE_OPERATOR \ typedef decltype(&call) function_type; \ operator function_type(void) const \ { \ return &call; \ } template <typename Lambda,typename C,typename R> struct lambda_wrapper<Lambda,R (C::*)(void) const> { static R call(void) { Lambda x; return x(); } DEFINE_OPERATOR }; template <typename Lambda,typename R,typename A0> struct lambda_wrapper<Lambda,R (C::*)(A0) const> { static R call(A0&& p0) { Lambda x; return x(std::forward<A0>(p0)); } DEFINE_OPERATOR }; // and so on #undef DEFINE_OPERATOR } // wraps a lambda and provides // a way to call it statically template <typename Lambda> struct lambda_wrapper : detail::lambda_wrapper<Lambda,decltype(&Lambda::operator())> {}; template <typename Lambda> lambda_wrapper<Lambda> wrap_lambda(const Lambda&) { return lambda_wrapper<Lambda>(); } int main(void) { auto l = [](){ std::cout << "im broked :(" << std::endl; }; std::function<void(void)> f = wrap_lambda(l); f(); }
让我知道如果有任何部分令人困惑.