Я пытаюсь использовать лямбду для передачи вместо указателя на функцию, но 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();
}
Мне кажется странным, что компилятор не может преобразовать такую лямбду впростой указатель на функцию, поскольку он не захватывает переменные - также в том случае, если это действительно так, я задаюсь вопросом, что можно сделать.
Является ли тип каждой лямбды уникальным?Поэтому я мог бы взломать шаблонную функцию, используя тип 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*)
в эквивалентный указатель на функцию.Похоже, что это станет ненужным в более поздней версии VS2010.
Так, как заставить это работать для лямбды с замыканиями?
ОБНОВЛЕНО СНОВА!
Работает для замыканий в 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;
}