2016-03-08 5 views
6

ho notato ci sono 2 modi per ottenere l'iteratore fine di un vettore (o altra classe contenitore):Differenza tra std :: end (myVector) e myVector.end()

std::end(myVector) 

e

myVector.end() 

Lo stesso vale per varie altre funzioni contenitore iteratori, begin, cend, cbegin, rend, rbegin, crend, crbegin, find, ecc Quello che sto chiedersi è se c'è qualche differenza funzionale tra questi? E se no, c'è qualche motivo storico per averli entrambi?

(Mi scuso se questo è un duplicato, ho cercato dappertutto, e ha trovato un sacco di fonti per l'uno o l'altro di questi metodi, ma nessuno che parla di entrambi o confronta i due.)

risposta

7

C'è un motivo storico: prima di C++ 11 esistevano solo le versioni delle funzioni membro. C++ 11 ha aggiunto i non membri, che funzionano anche con semplici array in stile C, quindi possono essere considerati più generali.

int a[] = {3, 1, 5, 67, 28, -12}; 
std::sort(std::begin(a), std::end(a)); 

Quando viene applicata a contenitori della libreria standard, l'effetto di std::begin e std::end è chiamare funzioni membro del contenitore begin() e end(), quindi non c'è differenza funzionale.

C++ 14 aggiunti std::cbegin, std::cend, , std::rend, std::crbegin e std::crend, con comportamento simile.

+0

Quindi l'unica differenza è che il nuovo metodo funziona anche sugli array? Va bene. Utile, immagino - potrei dover chiedere alla persona che ha scritto questo codice perché lo stiamo usando su 'vector's e semplicemente rendendo il codice inutilmente più prolisso, ma immagino che risponda alla mia domanda. –

+0

@DarrelHoffman Credo che sia una questione di scelta, ma preferisco usare le funzioni non membro, se possibile. BTW se il parametro è un contenitore di libreria standard, 'std ::' può essere omesso, e 'begin (v)' non è molto più prolisso di 'v.begin()'. – juanchopanza

+0

Sì, anche se potenzialmente pericoloso in questo caso - Gran parte del nostro codebase è condiviso da molti team in diverse parti del mondo, alcuni dei quali sono ancora in esecuzione C++ 0x per motivi legacy. Non mi aspetto che questa particolare parte del codice possa causare problemi, ma in passato ci sono stati dei conflitti. (Dobbiamo contrassegnare alcune classi come "No C++ 11 permesso" in modo che non rompa le build degli altri team ...) –