2012-03-09 8 views
8

posso effettuare le seguenti operazioni in C++Esiste un metodo generico foreach in Delphi per che può essere chiamata con funzione anonima

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

vorrei fare lo stesso/simile a Delfi. Ho chiesto a question in precedenza agli sviluppatori C++ e volevo produrre un esempio simile in OOP Pascal. La parte lambda (metodo anonimo) della domanda non è rilevante in realtà, ma mi chiedevo se potevo fare lo stesso in Delphi XE2.

Sto chiedendo perché ho XE, e non sono sicuro se è stato aggiunto. Grazie.

risposta

6

Probabilmente l'analogo Delphi più vicino a std::vector<T> è TList<T>. È possibile iterare la lista con un ciclo for in:

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

Se si dispone di un array dinamico piuttosto che un TList<T> quindi è possibile utilizzare for in per scorrere gli elementi. Infatti, tutti i contenitori integrati supportano for in ed è facile aggiungere il supporto per for in alle proprie classi.

In C++ non c'è niente come un ciclo for in e quindi l'idioma è usare un algoritmo STL. Questo è ciò che ti spinge ad usare una funzione anonima. In Delphi con la sintassi for in è possibile esprimere "iterate su tutti i membri del contenitore" in modo naturale senza ricorrere a metodi anonimi.

I generici sono stati aggiunti a Delphi a Delphi 2009 e il ciclo for in è stato aggiunto in Delphi 2005, quindi tutto questo è disponibile in XE. Per quello che vale, sono stati aggiunti anonimi anche a Delphi 2009.

Quello che devi capire è che i generici di Delphi sono meno potenti dei modelli C++. Sebbene si parli di un generico foreach, il codice non è generico nel senso che è specializzato in int. Potresti scrivere una versione generica del tuo codice in C++, ma ciò sarebbe molto più difficile da fare con i generici Delphi a causa dei limiti intrinseci dei generici rispetto ai modelli. Un tentativo di scrivere il codice di cui sopra in modo generico in Delfi sarebbe il fondatore nel punto in cui hai provato a chiamare Writeln. Anche se ciò sarebbe banale con i modelli C++, è frustrantemente irraggiungibile per i generici.

Aggiornamento: Nei commenti si chiede se c'è un modo intelligente per aggiungere il contenuto di un contenitore a un altro. Il metodo AddRange lo fa. TList<T>.AddRange() ha tre varianti di overload che ricevono uno dei seguenti parametri di input: array of T, Collection: IEnumerable<T> o Collection: TEnumerable<T>. Tutti i contenitori generici standard seguono uno schema simile.

+0

Ecco come l'ho fatto: per i: = da 0 a n - 1 do result.Add (i); Ma mi chiedevo se esistesse una tale funzione generica :) – Mihaela

+3

La sintassi Lambda/Chiusura/Anonfunzione è così CLUNKY in delphi che è piuttosto bello che non ne abbia bisogno per cicli 'for'. Gli idiomi C++ come al solito, non si traducono bene in pascal. Ma C# e Delphi sono piuttosto vicini. –

+0

Lo trovo abbastanza utile in C++. Non solo è il pulitore del codice (per le piccole funzioni anonime), ma in C++ viene spesso inserito e genera un codice più veloce. – Mihaela