auto it = vector.begin() resulting type is not convertible to const_iterator

会有一股神秘感。 提交于 2019-12-01 06:40:53

Your problem can be reduced to the following example, which fails for the same reasons.

#include <vector>
#include <iterator>
int main()
{
    std::vector<int> v;
    std::vector<int>::const_iterator it1 = v.begin();
    auto it2 = v.end();
    auto n = std::distance(it1, it2);
}

std::distance is defined using the same template parameter type for both arguments, and template argument deduction is failing because you have a const_iterator and iterator.

User defined conversions are not considered when deducing template arguments from function calls, and since the two arguments have different types in this case, and both are participating in template argument deduction, the deduction fails.

§14.8.1/6 [temp.arg.explicit]

Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.

§14.8.2.1/4 [temp.over]

... [ Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter contains no template-parameters that participate in template argument deduction. Such conversions are also allowed, in addition to the ones described in the preceding list. —end note ]

You'll need to convert the iterator to const_iterator, or specify the template argument to std::distance explicitly.

auto n = std::distance(it1, static_cast<decltype(it1)>(it2));

or

auto n = std::distance<decltype(it1)>(it1, it2);

Other options are, of course, to not use auto and explicitly specify the iterator type in both cases, or use the vector::cbegin() and vector::cend() member functions when you need to ensure that the type is a const_iterator.

The problem has nothing common with the iterator conversion. The compiler simply unable to determine the template argument. It is the same if you would write

int x = 10;
long y = 20;

std::cout << std::max( x, y ) << std::endl;

though an object of type int can be implicitly converted to an object of type long.

As for your example you could write

const size_t n = std::distance<std::vector<char>::const_iterator> (it, itr);

Why does auto deduce a typ[e in this case that is not convertible to const_iterator?

  • You have two available overloads for begin() :

Signatures:

iterator begin();

const_iterator begin() const;

You declared your vector as Packets test (100);, which is non const.

If you declare it const, auto type deduction will have the second begin() overload as a best (and unique) match.

It compiles and run with this simple fix.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!