2013-06-25 13 views
6

(Sto avendo questi due typedef:iteratori STL std :: distanza) Errore

typedef std::vector<int> Container; 
typedef std::vector<int>::const_iterator Iter; 

Nel problema che considero, io eseguire alcune operazioni su Container Input, e dopo che mi piacerebbe calcolare std::distance(Input.begin(),itTarget) , dove itTarget è del tipo Iter. Ma sto ricevendo questo errore del compilatore da no instance of function template "std::distance" matches the argument list e solo dopo il casting, ovvero, std::distance(static_cast<Iter>(Input.begin()),itTarget), tutto funziona correttamente.

Mi chiedo perché?

+2

È perché 'begin()' non restituisce un 'const_iterator'? –

+0

Ma in qualche modo dovrebbe essere in grado? http://www.cplusplus.com/reference/vector/vector/begin/ –

+1

Questo è il modo in cui funzionano gli overload 'const' e non-'const'. Solo se 'Input' è' const'-qualificato verrà chiamato il overload 'const'. Inoltre, piuttosto che lanciare l'iteratore, è possibile chiamare specificare il tipo di modello: 'std :: distance (Input.begin(), itTarget)' –

risposta

8

std::distance è una funzione modello, non può accettare parametri diversi. È necessario utilizzare:

std::distance(Input.cbegin(),itTarget); 
        ^^ 

vedere std::vector::cbegin collegamento

+1

3a volta l'incantesimo: P –

+0

e cbegin() restituisce const iterator? –

+0

@SimonRighley yup, guarda il link aggiornato – billz

5

Input.begin() restituisce un iterator invece di un const_iterator, e il secondo argomento è un const_iterator, in modo che i due argomenti sono fondamentalmente di tipo diverso. È possibile utilizzare cbegin() se si ha accesso a Funzionalità C++ 11.

Un secondo modo di farlo: Ogni iteratore è trasformabile in const_iterator mediante cessione

std::vector<int> myVector(100); 
std::vector<int>::iterator it = myVector.begin(); 
std::vector<int>::const_iterator cit = it; 

Se si dispone di mettere in valigia le cose nella funzione di chiamata si potrebbe usare un po 'di fusione di magia:

std::distance(((const Container*)&Input)->begin(), itTarget); 

Se Input è const, il compilatore è obbligato a utilizzare la versione const di begin(), che restituisce un const_iterator.

+0

Un cast funziona con gli iteratori del vettore perché solitamente sono semplicemente un typedef per 'T *' e 'const T *'. Potrebbe non funzionare con iteratori che sono classi. – jrok

+0

Scratch che, come "iteratore", dovrebbe sempre essere convertibile in "const_iterator'. – jrok

+0

Convertibile, sì. Calcinabile? Non sarei così sicuro Aggiornato la mia risposta. – Marius

Problemi correlati