Like the question says, I'm wondering about the reason for that. Because I get an error when I try to get the distance between const
and non-const
iterators.
vector<int> v;
auto it=v.begin();
auto cit=v.cbegin();
distance(it,cit);
no matching function for call to ‘distance(__gnu_cxx::__normal_iterator<int*, std::vector<int> >&, __gnu_cxx::__normal_iterator<const int*, std::vector<int> >&)
From my limited understanding of iterators, I see no reason why it shouldn't work.
You have a mutable iterator and a constant iterator in the call to std::distance
, so template argument deduction is failing. You can fix this by specifying the template argument explicitly.
std::vector<int> v;
auto i1 = v.begin();
auto i2 = v.cbegin();
auto dist = std::distance<std::vector<int>::const_iterator>( i1, i2 );
That's because std::distance() only takes one template parameter:
template <class InputIterator>
iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
Therefore, first
and last
must be convertible to the same type, and template resolution will unfortunately not consider that vector<int>::iterator
is convertible to vector<int>::const_iterator
.
As everyone says, it's because std::distance
only takes one iterator type, and template argument deduction is not able to choose which one it should be (even though only one of them is possible given that iterator
converts to const_iterator
but not back).
It might be worth writing a template something like this:
template <typename Container>
typename Container::const_iterator constify(const Container &, typename Container::iterator it) {
return it;
}
Then you can force the template deduction like this:
std::distance(constify(v, it), cit);
instead of writing out that great long type. The Container&
parameter is a shame, it's there because AFAIK Container
can't be deduced from an iterator argument alone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With