iam*_*iam 10 c++ lambda visual-studio-2010 c++11
我试图使用lambda代替函数指针,但VS2010似乎无法转换它.我试过像这样使用std :: function它崩溃了,我不知道我这样做是否合适!
#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();
}
Run Code Online (Sandbox Code Playgroud)
对我来说,编译器无法将这样的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();
}
Run Code Online (Sandbox Code Playgroud)
再次更新
所以在给出的帮助下我得出了更短的内容:
template<typename Signature>
void (*LambdaBind(Signature))(void*)
{
struct Detail
{
static void Bind(void* parameter)
{
Signature method;
method(parameter);
}
};
return &Detail::Bind;
}
Run Code Online (Sandbox Code Playgroud)
这可以用于将没有闭包的lambda包装void(*)(void*)到等效函数指针中.看来在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;
}
Run Code Online (Sandbox Code Playgroud)
在VS2010实现它们之后添加了lambda的这个特性,因此它们还不存在.
这是一个可能的通用解决方案,非常未经测试:
#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 C, 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();
}
Run Code Online (Sandbox Code Playgroud)
如果任何部分令人困惑,请告诉我.
| 归档时间: |
|
| 查看次数: |
8022 次 |
| 最近记录: |