2009-09-29 6 views
6

He estado leyendo un poco sobre expresiones lambda en Internet recientemente y me parece que las expresiones lambda de C++ 0x no tendrán un solo tipo (o tipos) que se unirá exclusivamente a expresiones lambda - en otras palabras , las expresiones lambda solo coincidirán con argumentos de plantilla o argumentos/variables auto. Lo que sucede, como se describe here, es que¿Es malo que las expresiones lambda de C++ 0x no tengan un tipo con nombre?

compiladores que apoyan lambdas se crear una única funtor tipo anónimo para cada expresión lambda

Mi pregunta es, ¿es malo? ¿No tendría sentido tener alguna palabra clave que coincida solo con expresiones lambda, p. lambda, que tendría las características siguientes

void f(std::function<int(int)> func) 
{ 
    func(2); 
} 

template<typename T> 
void g(T func) 
{ 
    func(2); 
} 

void h(lambda func) 
{ 
    func(2); 
} 

int main() 
{ 
    int fpointer(int); 
    struct { int operator()(int var) { return var; } } functor; 

    f(fpointer); //ok (actually a linker error, but for the sake of example) 
    f(functor); //ok 
    f([](int var) { return var; }); //ok 

    g(fpointer); //ok 
    g(functor); //ok 
    g([](int var) { return var; }); //ok 

    h(fpointer); //error -- function pointer isn't a lambda expr 
    h(functor); //error -- functor isn't a lambda expr 
    h([](int var) { return var; }); //ok 

    return 0; 
} 

Para ser honesto, realmente no se puede ver la utilidad de este (especialmente teniendo en cuenta que auto acepta expresiones lambda, por lo que uno puede entonces asignar un lambda a una variable), pero todavía no me sienta bien que las expresiones lambda sean anónimas y no puedan vincularse específicamente a un solo tipo (con exclusión de todas las demás).

En esencia, mi pregunta es, ¿está bien que las expresiones lambda sean anónimas (tanto en términos de utilidad, la falta de un tipo lambda nos despoja de alguna funcionalidad, y filosóficamente, tiene sentido? que las expresiones lambda siempre tienen el 'tipo' auto)?

+6

Suena como si no fuera consciente de que puede aceptar expresiones lambda usando 'std :: function ' también. –

+0

Yo estaba, sin embargo, ya que la funcionalidad general coincide con cómo funciona 'auto' (afaik), pensé que era innecesario agregar * otro * conjunto de funciones de ejemplo/llamadas a función (pero aún así es bueno mencionarlo, así que gracias, literalmente) – GRB

+2

Creo hay un malentendido sobre el auto. auto no se puede usar como un tipo de parámetro en una función. No es un tipo. auto solo dice "deduce el tipo del inicializador porque soy demasiado vago o simplemente no puedo nombrar el tipo". – sellibitze

Respuesta

11

Lambdas son tipos independientes. El código

void h(lambda func) 
{ 
    func(2); 
} 

no tiene ningún sentido porque las lambdas no tienen polimorfismo de tiempo de ejecución. Recuerde que una lambda es el equivalente a

struct unique_name 
{ 
    return_type operator()(Arg1 a1, Arg2 a2, ... , Argn an) 
    { 
     code_inside_lambda; 
    } 
} 

que es en sí mismo un tipo único. El código anterior sería lo mismo que decir

void h(class C) 
{ 
    C(2); 
} 

Lo que también no tiene sentido incluso si asegurar que C tiene operator(). Necesita una plantilla:

template<typename T> 
void g(T func) 
{ 
    func(2); 
} 

int main() 
{ 
    g([](int x){return x + 2;}); 
} 
+0

Haces un buen punto acerca de la idea de tener 'void h (clase C)', sin embargo, yo * puede * hacer 'void h (nombre_del_functor C)' que solo coincidirá con los parámetros de ese tipo de functor en particular. No puedo hacer lo mismo con una expresión lambda. – GRB

+1

Si necesita referirse a un lambda en particular por su nombre, en su lugar debe definirlo de la manera antigua con una 'struct'. Una expresión lambda es, por definición, anónima. – rlbond

+0

Ese es un buen punto, si necesita especializarse en expresiones lambda (aunque no proporcionaría ninguna funcionalidad) probablemente las esté usando incorrectamente de todos modos (y iría en contra de la teoría de las epxressions lambda). Además, como mencioné y como todos han mencionado, probablemente no haya utilidad (aunque es cierto que alguien agregará una extensión de compilador no estándar). He aceptado esta respuesta – GRB

3

No veo ninguna razón para diferenciar los tipos de funciones según si la función tiene un nombre o no. Las funciones de Lambda son solo una abreviatura, lo que le permite definir fácilmente una función de conveniencia. Nombre o no nombre, el comportamiento de la función cuando se llama es el mismo.

Piénsalo de esta manera. Una versión anterior de su software tiene un predicado definido como una función anónima. Con el tiempo, los requisitos se vuelven más complejos y tu predicado también se vuelve más complejo, y tal vez necesites llamarlo desde más de un lugar. Lo más sensato es refactorizar para que tenga una función con nombre.

No hay ninguna razón por la cual la función llamada (la que llama al predicado) debería preocuparse por eso. Simple o complejo, nombrado o anónimo: sigue siendo solo una función de predicado.

Un problema menor es el de los cierres: no lo he comprobado, pero con un poco de suerte, C++ obtendrá anidadas funciones con cierres y lambdas.

Cuestiones relacionadas