2010-03-05 9 views
11

Con STL :: vector:limiti Disabilitare il controllo per C++ vettori

vector<int> v(1); 
v[0]=1; // No bounds checking 
v.at(0)=1; // Bounds checking 

C'è un modo per disattivare controllo dei limiti, senza dover riscrivere tutto at() come []? Sto usando la libreria GNU Standard C++.

Edit: ho cambiato at()-[] nella zona in cui sospettavo un collo di bottiglia, e ha ridotto in modo significativo il tempo di calcolo. Tuttavia, poiché eseguo l'iterazione tra lo sviluppo del codice e l'esecuzione di esperimenti con esso, vorrei abilitare il controllo dei limiti durante lo sviluppo e disabilitarlo quando eseguo gli esperimenti per davvero. Immagino che il consiglio di Andrew sia la soluzione migliore.

+6

A che scopo? Potrebbe esserci un modo migliore. –

+0

Dovresti essere in grado di usare un'espressione regolare per sostituire 'at()' con '[]' e impostare un punto di interruzione per verificare che tutte le istanze siano state sostituite. Non che scivolare attraverso sarebbe un disastro, la preoccupazione è solo la prestazione, giusto? – Potatoswatter

+4

Perché dovresti farlo? Se la tua risposta è la performance, per favore dimmi che hai profilato e hai scoperto che questo è il collo di bottiglia. Se questo è il caso, allora sì, riscrivi i tuoi at() come '[]'. Altrimenti, lascia che sia. –

risposta

15

No. Il controllo dei limiti di std::vector::at è specificato dallo standard e non esiste un'implementazione C++ conforme allo standard che possa deviare da quella.

3

Non è un modo standard. È possibile disattivare le eccezioni nel compilatore. Puoi farlo con gcc con -fno-exceptions.

Si dovrebbe fare attenzione a questo; le tue librerie (comprese le librerie standard) potrebbero non funzionare bene con le eccezioni disattivate. Controlla la tua documentazione e discussioni come this one on the gcc mailing list.

+0

Non penso che questo sia un buon approccio ma +1 per il collegamento. – Potatoswatter

6

Forse una soluzione migliore è utilizzare [] e utilizzare l'implementazione verificata della libreria standard per il debug.

23

Se si vuole veramente farlo (almeno per un confronto rapido e sporco profiling), questo funzionerà se si dispone di nessun altro at() s

#define at(x) operator[](x) 

E se si desidera mantenere at() per lo sviluppo e utilizzare operator[] in produzione, basta avvolgerlo in un #ifdef.

E se si dispone di altri at() s è sempre possibile modificare il file #include d <vector>.

+0

+1 In ritardo alla festa, ma con ottimi consigli. Questo è sicuramente il modo rapido e sporco per profilare qualcosa. –

+0

+1 questo sarebbe stato il mio suggerimento – imallett

0

Se si dispone di modelli ragionevolmente coerenti di accesso (vale a dire/non ad accesso casuale), piuttosto che utilizzando at() o [], un approccio al fine di evitare il controllo dei limiti è quello di utilizzare gli iteratori, utilizzando begin(), end() e advance() o meglio ancora, attraverso la uso degli algoritmi standard.

Anche se questo non risolve il problema di fondo di correggere at() facendo gamma controllando alcune implementazioni della libreria standard (MSVC) hanno controllato iteratori per alcuni tipi delle generazioni

3

Sulla base di un commento che si desidera attivare on/off il controllo dei limiti, è possibile utilizzare una funzione di modello di avvolgitore:

template <class T> 
inline typename T::reference deref(T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

template <class T> 
inline typename T::const_reference deref(const T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

si dovrà modificare il codice per attivare questo, ma una volta che si aveva al suo posto si poteva girare legato controllo o disattivare a piacere .

Ammetto che sembra un po 'brutto da usare:

deref(vec, 10) = ...; 
2

derivare la propria classe vettore nel proprio spazio dei nomi come "uncheckedvector", e sovrascrivere la a() del tipo di base vettoriale per usare l'indice dell'array.

Quindi utilizzare "using uncheckedvector :: vector" consente di ignorare tutti gli usi del vettore in qualsiasi punto. Questo non funzionerà se si usano ovunque tipi qualificati ovunque.

+0

-1: mai ereditato dai tipi STL, mancano distruttori virtuali. – Joh

2

Usa at() quando si sempre desidera controllare. Si noti inoltre che questa eccezione genera un errore, quindi è potenzialmente recuperabile. Se si desidera la funzione di accesso più veloce, deselezionata, utilizzare [], ma gli algoritmi che ne fanno uso devono essere testati a fondo perché la modalità di errore è più grave (comportamento non definito).

Un paio di approcci per limiti di sviluppo a modalità di controllo per [] quando si usa GCC su Linux:

Qualche altra discussione interessante: vector::at vs. vector::operator[]

Problemi correlati