2012-05-24 8 views
16

Quando si desidera accedere a un vettore std :: come un array C è possibile scegliere tra almeno quattro modi diversi, come si può vedere in questo esempio:std :: vector: vec.data() o & vec [0]

#include <iostream> 
#include <vector> 

using namespace std; 

int main() { 
    std::vector<int> vec; 
    vec.push_back(1); 
    vec.push_back(2); 
    vec.push_back(42); 
    vec.push_back(24024); 
    { 
    int* arr = vec.data(); 
    cout << arr << endl; /* output: 0x9bca028 */ 
    cout << arr[3] << endl; /* output : 24024 */ 
    } 
    { 
    int* arr = &vec.front(); 
    cout << arr << endl; /* output: 0x9bca028 */ 
    cout << arr[3] << endl; /* output : 24024 */ 
    } 
    { 
    int* arr = &vec[0]; 
    cout << arr << endl; /* output: 0x9bca028 */ 
    cout << arr[3] << endl; /* output : 24024 */ 
    } 
    { 
    int* arr = &vec.at(0); 
    cout << arr << endl; /* output: 0x9bca028 */ 
    cout << arr[3] << endl; /* output : 24024 */ 
    } 
} 

Quello che ho trovato nella maggior parte dei casi è il &vec[0]. Penso che sia il meno elegante, quindi ... perché è il più usato? È più efficiente o più compatibile? Non riesco a trovare molta documentazione su data().

+1

'data()' * may * essere considerato incompatibile nel senso che è C++ 11 (che spiega la scarsa documentazione, in quanto le principali fonti di documentazione stanno recuperando nuove funzionalità), anche se il tempo sicuramente farà svanire questa incompatibilità e quindi è la via definitiva da percorrere. –

risposta

16

data() è nuovo di zecca per C++ 11, ecco perché non lo vedi così spesso. L'idea di usare &vec.front() non mi è mai venuta in mente, probabilmente perché uso operator[] molto più spesso di front() (quasi mai). Immagino sia lo stesso per gli altri.

+0

I dati non sono costanti? –

+0

@MooingDuck: solo per i vettori const, [penso] (http://en.cppreference.com/w/cpp/container/vector/data). Lo proverò ora. –

+7

@MooingDuck No. È stato aggiunto esattamente così le persone non dovrebbero scrivere: 'v.empty()? NULL: & v [0]'. – bames53

14

Se si utilizza C++ 11, quindi utilizzare data() è decisamente preferibile. In particolare, se il vettore è vuoto, l'utilizzo di una delle altre due opzioni produce un comportamento indefinito! Se non stai usando C++ 11 e il vettore potrebbe essere vuoto, assicurati di controllare quella condizione.

1

Prima di C++ 11 std::array Direi che std::vector era il contenitore più comune da utilizzare al posto dell'array in stile C. L'operatore [] di solito implica l'accesso costante al tempo (che è tutto ciò che è std::vector) e quindi la maggior parte dei programmatori di solito sceglie questo stile per riflettere l'accesso e il comportamento di tipo array.

0

data() è stato parte di std::string per un po 'di tempo, quindi è possibile leggere su questo. Ho trovato l'implementazione data() in std::vector simile. Occasionalmente uso data() per trattare uno std::string come una matrice di byte non elaborati.

4

Utilizzare & vec [0] è il più comune anche se, concordo, sembra un po 'strano. Una cosa da tenere a mente per il futuro. Se il tuo vettore sembra essere un vettore di oggetti la cui classe sovraccarica l'operatore &(), rendi conto che ciò causerà uno strano comportamento se chiami & vec [0].

Questo non otterrà l'indirizzo iniziale del primo elemento nell'array contiguo interno di oggetti, restituirà qualsiasi vec [0] .operator &() restituirebbe. La maggior parte se non tutte le volte, non è l'indirizzo che stai cercando (onda della mano Jedi).

Un buon esempio di questo è CComPtr di ATL. Sovraccarica l'operatore &() quindi memorizzarlo in un vettore può essere problematico. Per aggirare questo problema, ATL ha una classe template CAdapt che può essere utilizzata per nascondere l'operatore &() su CComPtr

+2

+1 per il problema di overload dell'operatore &() –

Problemi correlati