就像问题所说,我想知道原因。因为当我试图获得const
和非const
迭代器之间的距离时出现错误。
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> >&)
根据我对迭代器的有限理解,我认为没有理由不这样做。
答案 0 :(得分:20)
在std::distance
的调用中有一个可变迭代器和一个常量迭代器,因此模板参数推断失败。您可以通过明确指定模板参数来解决此问题。
std::vector<int> v;
auto i1 = v.begin();
auto i2 = v.cbegin();
auto dist = std::distance<std::vector<int>::const_iterator>( i1, i2 );
答案 1 :(得分:6)
那是因为std::distance()只接受一个模板参数:
template <class InputIterator>
iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
因此,first
和last
必须可转换为相同的类型,但遗憾的是,模板解析不会认为vector<int>::iterator
可转换为vector<int>::const_iterator
。
答案 2 :(得分:4)
正如大家所说,这是因为std::distance
只接受一个迭代器类型,而模板参数推导无法选择它应该是哪一个(即使iterator
只有其中一个是可能的转换为const_iterator
但不回复。
可能值得写一个这样的模板:
template <typename Container>
typename Container::const_iterator constify(const Container &, typename Container::iterator it) {
return it;
}
然后你可以像这样强制模板扣除:
std::distance(constify(v, it), cit);
而不是写出那么长的类型。 Container&
参数很遗憾,因为AFAIK Container
不能仅从迭代器参数中推断出来。
答案 3 :(得分:3)
std::distance
将与这两个迭代器一起工作,不起作用的是模板参数推断。编译器正在尝试解析用什么类型替换第一个模板参数,并且有两个潜在的候选者,按照标准最终会失败。
您可以执行以下两种操作之一,或者仅比较相同类型的迭代器,或者为模板提供类型:
std::distance<std::vector<int>::const_iterator>( v.begin(), v.cbegin() );