为什么STL需要一个临时迭代器变量来编译它?

时间:2015-02-13 10:36:14

标签: c++ stl iterator

这是一段非常简单的代码:

#include <vector>

int main() {

    std::vector<int> myVec(5);
    std::vector<int>::const_iterator first = myVec.begin();
    std::vector<int>::const_iterator last = myVec.begin() + 3;
    std::vector<int> newVec1(first, last);
    std::vector<int> newVec2(myVec.begin(), last);

    return 0;
}

行声明newVec1编译。

行声明newVec2失败并显示以下错误:

prog.cpp: In function 'int main()':
prog.cpp:11:49: error: no matching function for call to 'std::vector<int>::vector(std::vector<int>::iterator, std::vector<int>::const_iterator&)'
     std::vector<int> newVec2(myVec.begin(), last);
                                                 ^
prog.cpp:11:49: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
                 from prog.cpp:3:
/usr/include/c++/4.9/bits/stl_vector.h:401:9: note: template<class _InputIterator, class> std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&)
         vector(_InputIterator __first, _InputIterator __last,
         ^
/usr/include/c++/4.9/bits/stl_vector.h:401:9: note:   template argument deduction/substitution failed:
prog.cpp:11:49: note:   deduced conflicting types for parameter '_InputIterator' ('__gnu_cxx::__normal_iterator<int*, std::vector<int> >' and '__gnu_cxx::__normal_iterator<const int*, std::vector<int> >')
     std::vector<int> newVec2(myVec.begin(), last);
                                                 ^
In file included from /usr/include/c++/4.9/vector:64:0,
                 from prog.cpp:3:
/usr/include/c++/4.9/bits/stl_vector.h:373:7: note: std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(initializer_list<value_type> __l,
       ^
/usr/include/c++/4.9/bits/stl_vector.h:373:7: note:   no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::initializer_list<int>'
/usr/include/c++/4.9/bits/stl_vector.h:348:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(vector&& __rv, const allocator_type& __m)
       ^
/usr/include/c++/4.9/bits/stl_vector.h:348:7: note:   no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>&&'
/usr/include/c++/4.9/bits/stl_vector.h:339:7: note: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(const vector& __x, const allocator_type& __a)
       ^
/usr/include/c++/4.9/bits/stl_vector.h:339:7: note:   no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'const std::vector<int>&'
/usr/include/c++/4.9/bits/stl_vector.h:335:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&) [with _Tp = int; _Alloc = std::allocator<int>]
       vector(vector&& __x) noexcept
       ^
/usr/include/c++/4.9/bits/stl_vector.h:335:7: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:318:7: note: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = int; _Alloc = std::allocator<int>]
       vector(const vector& __x)
       ^
/usr/include/c++/4.9/bits/stl_vector.h:318:7: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:289:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::value_type = int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(size_type __n, const value_type& __value,
       ^
/usr/include/c++/4.9/bits/stl_vector.h:289:7: note:   no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>::size_type {aka unsigned int}'
/usr/include/c++/4.9/bits/stl_vector.h:277:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(size_type __n, const allocator_type& __a = allocator_type())
       ^
/usr/include/c++/4.9/bits/stl_vector.h:277:7: note:   no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>::size_type {aka unsigned int}'
/usr/include/c++/4.9/bits/stl_vector.h:264:7: note: std::vector<_Tp, _Alloc>::vector(const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
       vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
       ^
/usr/include/c++/4.9/bits/stl_vector.h:264:7: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:253:7: note: std::vector<_Tp, _Alloc>::vector() [with _Tp = int; _Alloc = std::allocator<int>]
       vector()
       ^
/usr/include/c++/4.9/bits/stl_vector.h:253:7: note:   candidate expects 0 arguments, 2 provided

g ++和Visual Studio都无法编译这个,任何想法为什么? myVec.begin()first ...

相同

2 个答案:

答案 0 :(得分:34)

myVec.begin()first不同。 first的类型为std::vector<int>::const_iterator,而myVec.begin()的类型为std::vector<int>::iterator

如果需要const迭代器,请使用cbegin

std::vector<int> newVec2(myVec.cbegin(), last);

答案 1 :(得分:2)

vec.begin()first不同,因为它会返回一个迭代器,而不是const_iterator

这是因为拥有const或非const迭代器取决于您对容器的访问类型,而不是您希望使用迭代器的用途,这也是例如创建代理的原因唯一的方法是在类似数组的对象::operator[]中分离读取和写入操作,而不是仅仅依赖于const或非const版本。

这只是const-correctness概念显示其局限性的许多情况。