2013-06-25 11 views
6

Mam takie dwie typedefs:STL Iteratory std :: odległości() Błąd

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

w problem, że uważam, że wykonanie pewnych czynności na Container Input, a potem chciałbym obliczyć std::distance(Input.begin(),itTarget) , gdzie itTarget jest typu Iter. Ale otrzymuję ten błąd kompilatora, że ​​no instance of function template "std::distance" matches the argument list, i tylko po casting, tj. std::distance(static_cast<Iter>(Input.begin()),itTarget) wszystko działa dobrze.

Zastanawiam się, dlaczego tak jest?

+2

Czy to dlatego, że 'begin()' nie zwraca 'const_iterator'? –

+0

Ale jakoś to powinno być możliwe? http://www.cplusplus.com/reference/vector/vector/begin/ –

+1

W ten sposób działają przeciążenia 'const' i non' 'constst'. Tylko jeśli 'Input' ma wartość' const', zostanie wywołane przeciążenie 'const'. Ponadto, zamiast rzucać iterator, możesz wywołać typ szablonu: 'std :: distance (Input.begin(), itTarget)' –

Odpowiedz

8

std::distance jest funkcją szablonu, nie może przyjmować różnych parametrów. Trzeba użyć:

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

zobaczyć std::vector::cbegin Link

+1

Po raz trzeci urok: P –

+0

i cbegin() zwraca const iterator? –

+0

@SimonRighley yup, zobacz zaktualizowany link – billz

5

Input.begin() zwraca iterator zamiast const_iterator, a drugi argument jest const_iterator, więc oba argumenty są zasadniczo innego rodzaju. Jeśli masz dostęp do funkcji C++ 11, możesz użyć cbegin().

Drugi sposób to zrobić: Każdy iterator jest zamienny do const_iterator przez przypisanie

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

Jeśli masz spakować rzeczy do wywołania funkcji można użyć trochę magii Obsada:

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

Jeśli Input jest const, kompilator jest zmuszony użyć const-wersji begin(), która zwraca const_iterator.

+0

Odlew działa z iteratorami wektorów, ponieważ zwykle są typedef dla 'T *' i 'const T *'. Może nie działać z iteratorami, które są klasami. – jrok

+0

Scratch, który wygląda jak "iterator", zawsze powinien być konwertowalny na 'const_iterator'. – jrok

+0

Kabriolet, tak. Castable? Nie byłbym tego taki pewien. Zaktualizowałem moją odpowiedź. – Marius

Powiązane problemy