2012-12-27 12 views
7

Come si definiscono gli iteratori di forward-output in C++ 11 in modo canonico?Modo canonico per definire l'iteratore di output in avanti

Secondo lo standard un forward_iterator è solo un input_iterator. Pertanto, lo forward_iterator_tag corrispondente si estende solo a input_iterator_tag. Se stiamo usando std::iterator per definire i nostri iteratori, quale tag utilizziamo per un iteratore di output in uscita?

È canonico per definire un tag privato che estende sia forward_iterator_tag e output_iterator_tag o c'è una soluzione migliore?

+0

che eredita da entrambi farà –

+0

Come una domanda a parte: qualcuno sa se questi tag iteratori mutabili sono stati considerati per la libreria standard? E se sì, perché non sono stati inclusi? –

risposta

6

La cosa canonica da fare è ereditare solo da std::iterator<std::forward_iterator_tag, T>. Gli iteratori hanno una sola categoria.

Lo standard non ha algoritmi (o altri usi) per un iteratore di output che è anche un iteratore in avanti. Tutti gli usi degli iteratori di output nello standard richiedono solo passaggio singolo.

Invece, lo standard ha l'idea di iteratori mutabili rispetto a immutabili di categorie forward/bidi/randomaccess. Tutti gli algoritmi che devono scrivere attraverso gli iteratori e che richiedono di meglio del single-pass, leggono anche gli stessi iteratori che scrivono. Questo è std::remove, std::sort e altri algoritmi di muting.

La differenza tra iteratori mutabili e immutabili non viene rilevata dal tag iteratore, è determinata dal fatto che le espressioni di assegnazione siano ben formate. Ad esempio, se si passa un iteratore a std::sort immutabile, l'algoritmo non verrà compilato comunque, quindi non è generalmente necessario che un iteratore di input venga contrassegnato con output_iterator_tag. Tutti gli algoritmi che richiedono un OutputIterator funzionano solo con un mutabile ForwardIterator, ancora una volta non è necessario che venga contrassegnato con output_iterator_tag.

Se si hanno esigenze diverse da quelle degli algoritmi standard, non riesco a pensare immediatamente a un motivo per cui la proposta non funzionerà per gli iteratori. Ma non rileverà gli iteratori standard mutabili. Ad esempio, std::deque<int>::iterator e int* hanno la categoria iteratore random_access_iterator_tag, non il tag privato e non ha nulla a che fare con output_iterator_tag. Quindi probabilmente staresti meglio a definire la tua classe di tratti piuttosto che sperare di adattare lo iterator_traits::iterator_category esistente per fornire le informazioni che desideri.

+0

Grazie! Questo ha chiarito le cose abbastanza. Alla fine ciò implica che gli iteratori immutabili restituiscono riferimenti const/copie dell'elemento puntato su per impedire l'assegnazione tramite il riferimento restituito, giusto? – MFH

+1

@ MFH: giusto. Gli iteratori immutabili sui contenitori restituiscono 'const T &' (non ho controllato se sia effettivamente richiesto, o se invece è possibile restituire proxy). Altri iteratori immutabili possono restituire qualsiasi cosa convertibile in 'T'. –

Problemi correlati