Come dovrei scrivere un'interfaccia che prende una lista di elementi?

4

Sto scrivendo una funzione di libreria che prende una lista (o "mazzo") di elementi (diciamo Student ) e fa qualcosa con loro. Qual è il modo migliore per scrivere la firma della funzione nell'interfaccia?

  1. std::vector<Student> Il problema è che forse il mio chiamante non sta usando STL e quindi hanno bisogno di istanziare e popolare un vettore. Non pulito e le prestazioni soffre.
  2. Student* + numOfStudents non sembra giusto, questo non è C.
  3. Una funzione che accetta un iteratore di inizio e fine? Dovrebbe quindi essere implementato come una funzione modello?
posta ytoledano 06.04.2016 - 23:04
fonte

3 risposte

3

Se l'obiettivo è accettare quanti più tipi di "lista" possibili, allora dovresti scrivere una funzione template che accetta qualsiasi cosa, e nella tua implementazione usare le funzioni begin() e end() per ottenere iteratori per esso, oppure usa un ciclo foreach (che il compilatore implementerà per te usando begin() e end() ).

Funzionerà per gli array raw, tutte le classi container standard e tutte le classi contenitore non standard che emulano l'interfaccia contenitore standard. In effetti, quel livello di genericità è esattamente il motivo per cui le funzioni begin() e end() sono state aggiunte alla lingua.

Se hai davvero bisogno di accettare qualcosa , puoi comunque fornire sovraccarichi aggiuntivi che richiedono un iteratore di inizio e fine o un puntatore e una lunghezza.

    
risposta data 06.04.2016 - 23:26
fonte
5

Dato che stai scrivendo C ++, un modello di funzione che accetta una coppia di iteratori per l'inizio e (uno dopo l'altro) avrebbe senso.

Specialmente se questo codice riguarda più il futuro rispetto al passato, prenderei in considerazione la possibilità di lavorare con un Range. C'è una bozza delle Specifiche tecniche per intervalli e un'alta probabilità che (eventualmente una forma riveduta) verrà eventualmente aggiunto allo standard (forse in C ++ 17, eventualmente ritardato fino al C ++ 20).

Se vuoi lavorare / giocare un po 'con questo, Eric Neibler ha scritto una implementazione (ha anche scritto la maggior parte della proposta).

    
risposta data 07.04.2016 - 00:08
fonte
2

Il modo più simile a C ++ per passare un intervallo di elementi è passare gli iteratori; che come suggerisci, coinvolge i parametri del modello.

La ragione di ciò è che un intervallo rappresentato dagli iteratori può essere qualsiasi cosa, incluso:

  • Un contenitore completo
  • Un sotto-intervallo all'interno di un contenitore
  • Uno stream
  • Puntatori
  • Un 'inserter' (ad esempio std::back_inserter )
  • std::regex corrisponde a
  • Qualcosa da uno dei POCO o BOOST librerie

Se vuoi che la tua funzione sia il più generica e universalmente riusabile possibile, allora gli iteratori sono la soluzione naturale; in particolare se l'unica interfaccia di cui hai bisogno comprende concetti InputIterator (cioè ++ , * e != ).

    
risposta data 07.04.2016 - 00:12
fonte

Leggi altre domande sui tag