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

后端 未结 3 950
予麋鹿
予麋鹿 2021-01-13 02:41

Containers are required to provide an iterator type which is implicitly convertible to a const_iterator. Given this, I am trying to use auto

相关标签:
3条回答
  • 2021-01-13 02:53

    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.

    0 讨论(0)
  • 2021-01-13 02:58

    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.

    0 讨论(0)
  • 2021-01-13 03:11

    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);
    
    0 讨论(0)
提交回复
热议问题