2015-11-03 13 views
23

std::begin e std::end conoscere l'inizio e la fine di uno container o uno array.In che modo std :: end conosce la fine di un array?

È così facile conoscere end e begin di un vector ad esempio perché è una classe che fornisce queste informazioni. Ma come si conosce la fine di un array come il seguente?

int simple_array[5]{1, 2, 3, 4, 5}; 
auto beg=std::begin(simple_array); 
auto en=std::end(simple_array); 

std::begin non è difficile sapere da dove cominciare la matrice. Ma come fa a sapere dove finisce? Il numero intero costante 5 verrà memorizzato da qualche parte?

Apprezzerei se avessi una risposta con alcune informazioni di basso livello.

risposta

22

è il numero intero costante 5 verrà memorizzato in alcuni dove?

Sì, fa parte del tipo di matrice. Ma no, non è memorizzato da nessuna parte in modo esplicito. Quando si dispone di

int i[5] = { }; 

il tipo di i è int[5]. La risposta di Shafik parla di come questa lunghezza viene utilizzata per implementare end.

Se hai C++ 11, utilizzando constexpr sarebbe il modo più semplice per andare

template <typename T, size_t N> 
inline constexpr size_t 
arrLen(const T (&arr) [N]) { 
    return N; 
} 

Se avete un pre-C++ 11 compilatore dove constexpr non è disponibile, quanto sopra la funzione potrebbe non essere valutata in fase di compilazione. Quindi, in tali situazioni, è possibile utilizzare questo:

template <typename T, size_t N> 
char (&arrLenFn(const T (&arr) [N]))[N]; 

#define arrLen(arr) sizeof(arrLenFn(arr)) 

In primo luogo si dichiara una funzione che restituisce un riferimento ad un array di N char s cioè sizeof questa funzione ora sarebbe la lunghezza della matrice. Quindi abbiamo una macro per avvolgerla, in modo che sia leggibile alla fine del chiamante.

Nota: Due matrici dello stesso tipo di base ma con diverse lunghezze sono ancora due tipi completamente diversi. int[3] non corrisponde a int[2]. Array decay, tuttavia, otterrebbe un int* in entrambi i casi. Leggi How do I use arrays in C++? se vuoi saperne di più.

+0

Grazie, sembra che mi siano perse molte cose .. Dovrei davvero chiedere "Che cos'è un array? .. intendi che l'array è una sorta di piccola classe con un puntatore all'inizio e un numero di elementi? potresti indicarmi a sth che posso leggere in dettaglio? –

+2

Due matrici dello stesso tipo di base ma con diverse lunghezze sono ancora due tipi completamente diversi. 'int [3]' non è lo stesso di 'int [2]'. Il decadimento delle matrici, tuttavia, ti porterebbe un 'int * 'in entrambi i casi. Leggi [Come utilizzare gli array in C++?] (Http://stackoverflow.com/q/4810664/183120), se vuoi saperne di più sugli array. – legends2k

+0

sì, questo è esattamente ciò che concludo dalla tua risposta. grazie ancora –

24

Ma, come si conosce la fine di una matrice

Si utilizza un parametro di modello non-tipo di dedurre la dimensione della matrice, che può quindi essere utilizzato per produrre il puntatore fine. La firma C++ 11 dalla sezione cppreference per std::end è la seguente:

template< class T, std::size_t N > 
T* end(T (&array)[N]); 

Come note HVD, poiché viene passato per riferimento questo impedisce il decadimento di un puntatore.

L'implementazione sarebbe qualcosa di simile a:

template< class T, std::size_t N > 
T* end(T (&array)[N]) 
{ 
    return array + N ; 
} 

è l'intero costante 5 saranno conservati alcuni dove?

5 o N fa parte del tipo di matrice e quindi N è disponibile in fase di compilazione. Ad esempio, l'applicazione di sizeof a un array ci darà il numero totale di byte nell'array.

Molte volte vediamo un array passato per valore a una funzione. In tal caso, l'array decays to a pointer da digitare archiviato nell'array. Quindi ora le informazioni sulla dimensione sono perse. Il passaggio per riferimento ci consente di evitare questa perdita di informazioni e di estrarre la dimensione N dal tipo.

+0

grazie, che significa che la N è memorizzata da qualche parte? se sì, dove? –

+0

N viene memorizzato dalla funzione. Sarà perso una volta che la funzione ha terminato l'esecuzione. Se vuoi ottenere lo stesso effetto e restituire la dimensione dell'array puoi usare il codice fornito in questa risposta e solo restituire N. –

+0

@HumamHelfawi sai che ho perso il punto del tuo commento prima e ho capito mentre stavo pendolando cosa tu significava. Ho aggiornato la mia risposta per coprire correttamente il tuo commento. –

7

Poiché si passa un array a std::end e un array ha il tipo T [N]. std::end può dire quando la matrice termina guardando il N nel tipo.

Problemi correlati