Estoy tratando de usar una lambda para pasar en lugar de un puntero a la función, pero parece que VS2010 no puede convertirlo. He intentado usar std :: function como este y se bloquea y no tengo idea si lo estoy haciendo bien.C++ 0x Lambda para el puntero a la función en VS 2010
#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();
}
Parece extraño que el compilador no puede convertir un lambda como a un simple puntero de función, ya que recoge ninguna variable - también en el caso de que lo hizo me pregunto qué se puede hacer.
¿Es el tipo de cada lambda único? Entonces, ¿podría piratear con una función de plantilla usando el tipo lambdas como un argumento de plantilla para generar una función estática única que podría llamarse y optimizarse?
ACTUALIZADO
La continuación parece funcionar, pero ¿es seguro?
#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();
}
actualizado de nuevo
Así que con la ayuda dado que he llegado con el más corto:
template<typename Signature>
void (*LambdaBind(Signature))(void*)
{
struct Detail
{
static void Bind(void* parameter)
{
Signature method;
method(parameter);
}
};
return &Detail::Bind;
}
Esto puede ser usado para envolver un lambda sin cierre de void(*)(void*)
en el puntero de función equivalente. Parece que esto será innecesario en una versión posterior de VS2010.
Entonces, ¿cómo hacer que esto funcione para una lambda con cierres?
¡ACTUALIZADO OTRA VEZ!
Obras para cierres en VS2010 - ni idea de si es 'seguro', aunque ...
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;
}
[Related] (http://stackoverflow.com/questions/3321283/c0x-lambda-how-can-i-pass-as-a-parameter), no consideraría un duplicado. – GManNickG
Ah, eso ayudó ... ¿y ahora tengo un trabajo que no creo que sea seguro en mi pregunta actualizada? – iam
Parece lo suficientemente seguro. Te proporcionaré una solución más genérica. Debe eliminar 'Método de firma estático;' y en su lugar poner 'Método de firma;' dentro de la función. Está vacío, así que no costará nada de todos modos. – GManNickG