2012-03-09 10 views
8

que pueda hacer lo siguiente en C++¿Hay un método genérico foreach en Delphi para que pueda llamarse con función anónima

for_each(vec->begin(), vec->end(), [](int n){cout << n << " " << endl;}); 

me gustaría hacer lo mismo/similar en Delphi. Pregunté question antes a los desarrolladores de C++, y quería producir un ejemplo similar en OOP Pascal. La parte lambda (método anónimo) no es relevante en realidad, pero me preguntaba si podría hacer lo mismo en Delphi XE2.

Pregunto porque tengo XE, y no estoy seguro de si se ha agregado. Gracias.

Respuesta

6

Probablemente el análogo de Delphi más cercano a std::vector<T> es TList<T>. Se puede recorrer la lista con un bucle for in:

var 
    Item: Integer; 
    List: TList<Integer>; 
.... 
for Item in List do 
    Writeln(Item); 

Si tiene una matriz dinámica en lugar de un TList<T> entonces puede utilizar for in para iterar sobre los elementos. De hecho, todos los contenedores integrados admiten for in y es fácil agregar soporte para for in a sus propias clases.

En C++ no hay nada como un bucle for in, por lo que la expresión idiomática es utilizar un algoritmo STL. Eso es lo que te lleva a usar una función anónima. En Delphi con la sintaxis for in, puede expresar "iterar sobre todos los miembros del contenedor" de forma natural sin recurrir a métodos anónimos.

Se agregaron genéricos a Delphi en Delphi 2009 y se agregó el bucle for in en Delphi 2005, por lo que todo esto está disponible para usted en XE. Por lo que vale, también se agregaron anónimos en Delphi 2009.

Lo que debes tener en cuenta es que los genéricos Delphi son menos poderosos que las plantillas C++. Aunque hable de un genérico foreach, su código no es genérico en el sentido de que se ha especializado en int. Podría escribir una versión genérica de su código en C++, pero esto sería mucho más difícil de hacer con los genéricos de Delphi debido a las limitaciones inherentes de los genéricos en comparación con las plantillas. Un intento de escribir el código anterior de forma genérica en Delphi se fundará en el punto en el que intentó llamar al Writeln. Si bien eso sería trivial con las plantillas de C++, está frustrantemente fuera del alcance de los genéricos.

Actualización: En los comentarios, usted pregunta si hay una forma elegante de agregar el contenido de un contenedor a otro. El método AddRange hace eso. TList<T>.AddRange() tiene tres variantes sobrecargadas que reciben uno de los siguientes parámetros de entrada: array of T, Collection: IEnumerable<T> o Collection: TEnumerable<T>. Todos los contenedores genéricos estándar siguen un patrón similar.

+0

Así es como lo hice: para i: = 0 a n - 1 do result.Add (i); Pero me preguntaba si existía tal función genérica :) – Mihaela

+3

La sintaxis Lambda/Closure/Anonfunction es tan CLUNKY en delphi que es genial que no lo necesites para bucles 'for'. Los modismos de C++ como siempre, no se traducen bien a pascal. Pero C# y Delphi son bastante cercanos. –

+0

Lo encuentro bastante útil en C++. No solo es el código más limpio (para pequeñas funciones anónimas), sino que en C++ a menudo se inserta y genera código más rápido. – Mihaela

Cuestiones relacionadas