2012-12-18 18 views
10

Come posso condurre std::find su un array legacy senza effettuare una nuova std::vector/std::array da un array legacy esistente?std :: ricerca di un array di eredità

ad esempio:

int ar[N]; 

if (std::find(ar, ar + N, value) != &ar[N]){ /**/ } 

È &ar[N] un valore valido per il controllo della situazione quando non viene trovato nulla? Posso essere sicuro che sto facendo bene usando &ar[N] come un analogo di std::vector::end()?

risposta

19

Se si utilizza C++ 11, è possibile utilizzare:

int arr[N]; 
if (std::end(arr) == std::find(std::begin(arr), std::end(arr), value)) 
{ 
    // ... 
} 

Per C++ 98, è possibile utilizzare:

int arr[N]; 
int *begin = arr; 
int *end = begin + N; 

if (end == std::find(begin, end, value)) 
{ 
    // ... 
} 
+3

Non è difficile scrivere la propria versione di 'std :: begin' e' std :: end'. –

+0

@BenVoigt, ho aggiornato il codice. – utnapistim

+0

da aggiungere al commento dei commenti, anche il boost fornisce inizio e fine. – 111111

2

Is & ar [N] un valore valido per verificare la situazione quando non viene trovato nulla?

È possibile utilizzare ar+N invece di &ar[N], perché ar +N è sicuro ma &ar[N] cade nella regione di comportamento non definito (c'è un lungo dibattito su che in realtà).

Semanticamente parlando, il secondo argomento è in realtà fine della gamma, quindi tutto ciò che passa come secondo argomento viene restituito quando nulla si trova nella gamma. Nel tuo caso, ar + N è il secondo argomento, che indica anche fine dell'intervallo. Quindi puoi scrivere questo:

if (std::find(ar, ar + N, value) != (ar + N)) 
{ 
     //value found 
} 
+1

Sei sicuro che '& ar [N]' è legale? Non comporta il dereferenziamento? –

+0

@LuchianGrigore: Si tratta di un lungo dibattito ma la solita conclusione è a favore. – Nawaz

+1

C'è un linguaggio speciale per i puntatori che consente di rendere significativo l'indirizzo dell'elemento oltre la fine. Non esiste un tale comportamento speciale abilitato per i riferimenti, 'ar [N] 'produce un comportamento non definito in qualsiasi contesto valutato, incluso' & ar [N] '. –

3

La tua idea generale è buona. Ma ar[N] non è "riservato" per te. Dereferenziare una variabile non allocata porterà a un comportamento indefinito. Vogliamo confrontare il risultato std::find con ar + N, che non implica il dereferenziamento.

+1

La tua prima frase è "La tua soluzione è buona". ma poi dici che in realtà non va bene. Qual é? –

+0

Controllare l'indirizzo di ar [N] è davvero una buona soluzione. Ma ha bisogno di non dereferenziarlo. Scusa se non mi sono chiarito. – tomahh

+0

Stai dicendo "la tua soluzione è buona". La sua soluzione implica '& ar [N]', che chiaramente non va bene.Inoltre "Derefenringen una variabile non allocata potrebbe portare a un comportamento indefinito." implica che ci sono situazioni in cui non porterebbe a UB, che di nuovo è sbagliato. –

2

No, ar[N] dereferenziazioni un elemento dopo la fine dell'array, quindi è illegale.

Ricorda che ar[N] equivale a *(ar + N) - quindi è chiaramente un dereferenziamento.

Vai con ar + N invece. È legale avere un puntatore 1 dopo la fine di un array, è illegale dereferenziarlo.