2009-12-24 19 views
7

Estoy tratando de trabajar con lambda en C++ después de haberlos usado mucho en C#. Actualmente tengo una tupla boost (esta es la versión realmente simplificada).cómo guardar en caché un lambda en C++ 0x?

typedef shared_ptr<Foo> (*StringFooCreator)(std::string, int, bool) 
typedef tuple<StringFooCreator> FooTuple 

A continuación, cargo una función en el espacio de nombre global en mi FooTuple. Idealmente, me gustaría reemplazar esto con un lambda.

tuplearray[i] = FooTuple([](string bar, int rc, bool eom) -> {return shared_ptr<Foo>(new Foo(bar, rc, eom));}); 

No puedo entender cuál debe ser la firma de la función para la tupla lambda. Obviamente no es un puntero a la función, pero no puedo entender cuál debería ser la firma de una lambda. Los recursos para lambda son todos bastante delgados en este momento. Me doy cuenta de que C++ 0x está cambiando en este momento, pero tenía curiosidad sobre cómo hacer que esto funcione. También me doy cuenta de que hay formas más simples de hacer esto, pero estoy jugando con C++ 0x. Estoy usando el compilador Intel 11.1.

Respuesta

7

El operador -> establece el tipo de retorno de la lambda, en el caso de que no se devuelva, puede omitirse. Además, si el compilador puede inferirlo, puede omitir el tipo de devolución. Al igual que Terry, no se puede asignar un lambda a un puntero de función (GCC permite esta conversión de forma incorrecta) pero puede usar std :: function.

Este código funciona en GCC y VC10 (quitar TR1/Del incluye para VC):

#include <tr1/tuple> 
#include <tr1/functional> 
#include <tr1/memory> 

using namespace std; 
using namespace std::tr1; 

class Foo{}; 
typedef function<shared_ptr<Foo>(string, int, bool)> StringFooCreator; 
typedef tuple<StringFooCreator> FooTuple; 

int main() { 
    FooTuple f(
     [](string bar, int rc, bool eom) { 
      return make_shared<Foo>(); 
     } 
    ); 

    shared_ptr<Foo> pf = get<0>(f)("blah", 3, true); 
} 
+0

No funciona - una expresión lambda no es un puntero a la función. Es (conceptualmente) una clase de functor anónima. –

+0

de las cosas que he leído, el compilador debería poder resolverlo y me avisará si no puede. Lo echaré un vistazo. Gracias. – Steve

+0

@Terry hmm eso es extraño, porque este código se compila y se ejecuta en GCC en este momento. – joshperry

1

Usted debe ser capaz de almacenar una lambda en un std :: función. En su ejemplo, trate de almacenarla en un

std::function<std::shared_ptr<Foo>(std::string,int,bool)>

No se olvide de automóviles (aunque usted no será capaz de hacer una serie de automóviles de, etc).

+0

¿Conoces por casualidad el encabezado de std :: function? Google no me está ayudando ... – Steve

+0

también, ¿a qué te refieres con auto? – Steve

+2

std :: la función está en auto es otra característica de C++ 0x –

3

De Visual C++ Blog

I mencionado en el almacenamiento de lambdas Tr1 :: funciones. Pero no debe hacer que a menos que sea necesario, ya que tr1 :: function tiene algunos gastos generales. Si desea reutilizar un lambda, o simplemente desea darle un nombre, puede usar auto.

+1

'auto' no sirve de nada, ya que no se puede utilizar como un parámetro de tipo para un contenedor como' vector'. –

+0

Eso es cierto, solo quería mencionar los gastos generales. –

+0

En el compilador de Intel, el lambda con función es aún más rápido que el caché de un puntero de función. Aproximadamente 3-5% más rápido de mis pruebas. Gracias por el consejo. – Steve

Cuestiones relacionadas