2012-07-06 10 views
11

Variante A:I confronti tra iteratore e const_iterator sono inefficienti?

const auto end = whatever.end(); 
for (auto it = whatever.begin(); it != end; ++it) 
{ 
    // ... 
} 

Variante B:

const auto end = whatever.cend(); // note the call to cend insteand of end here 
for (auto it = whatever.begin(); it != end; ++it) 
{ 
    // ... 
} 

v'è alcuna ragione di credere che la variante B sarà meno efficiente di variante a, dal momento che la condizione del ciclo a confronto due diversi tipi di iteratori? Ciò causa una conversione implicita su it?

(end viene utilizzato più volte all'interno del ciclo, quindi il desiderio di issare fuori.)

+0

Per quale contenitore? –

+0

@David Nel mio caso specifico, è un 'std :: string', ma sono curioso in generale. – fredoverflow

risposta

12

In linea di principio, può essere meno efficienti e risultare in una conversione implicita con costi non-zero.

In pratica, iterator e const_iterator sono suscettibili di partecipare ad una relazione di ereditarietà (sia una deriva dall'altra, o entrambi derivano da un _iterator_base) tale che l'operatore di disuguaglianza è definito sulla classe di base e non v'è alcuna necessità di una conversione implicita (invece, l'iteratore più derivato viene ignorato). Anche in assenza di questi, è probabile che la conversione sia abbastanza semplice da essere integrata e ottimizzata.

libstdC++ ottimizza questi confronti in modo diverso, attraverso la definizione di operator== e operator!= tra iterator e const_iterator: http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a02037.html#l00295

libC++ non ha alcuna ottimizzazione: http://llvm.org/svn/llvm-project/libcxx/trunk/include/__tree - anche se ancora una volta il costruttore di const_iterator da iterator è così banale che avevo aspetto che sia completamente ottimizzato.

Problemi correlati