当我使用g ++编译器编译c ++时,错误意味着什么?

yan*_*831 29 c++ iterator compiler-errors vector

使用以下代码:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int> ivec;
    for(vector<int>::size_type ix = 0; ix != 10; ix++)
    {
        ivec.push_back(ix);
    }
    vector<int>::iterator mid = (ivec.begin() + ivec.end()) / 2;
    cout << *mid << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用g ++编译错误:

iterator_io.cpp: In function `int main()':
iterator_io.cpp:13: error: no match for 'operator+' in '(&ivec)->std::vector<_Tp,               _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>]() + (&ivec)->std::vector<_Tp, _Alloc>::end [with _Tp = int, _Alloc = std::allocator<int>]()'
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_iterator.h:654: note: candidates are: __gnu_cxx::__normal_iterator<_Iterator, _Container> __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator+(const typename std::iterator_traits<_Iterator>::difference_type&) const [with _Iterator = int*, _Container = std::vector<int, std::allocator<int> >]
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_bvector.h:261: note:                 std::_Bit_iterator std::operator+(ptrdiff_t, const std::_Bit_iterator&)
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_bvector.h:345: note:                 std::_Bit_const_iterator std::operator+(ptrdiff_t, const std::_Bit_const_iterator&)
/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_iterator.h:765: note:                 __gnu_cxx::__normal_iterator<_Iterator, _Container> __gnu_cxx::operator+(typename __gnu_cxx::__normal_iterator<_Iterator, _Container>::difference_type, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&) [with _Iterator = int*, _Container = std::vector<int, std::allocator<int> >]
Run Code Online (Sandbox Code Playgroud)

我知道ivec.end()不能用作普通的向量元素.但我无法理解错误信息的含义...关于operator +的一些信息?

Raf*_*cki 23

不能将两个迭代器一起添加.

operator+没有为两个迭代器定义,因为该操作没有意义.迭代器是指针的一种泛化 - 它们指向存储在容器中的特定元素.迭代器的总和指向哪个元素?

但是,当您使用向量时,可以向迭代器添加整数,如下所示:

vec.begin() + vec.size() / 2
Run Code Online (Sandbox Code Playgroud)

这就是为什么你有candidates are: (...)错误信息,然后是一些定义operator+.

在您的情况下,最好,最干净的方法是不使用迭代器,但只是从指定位置获取值:

int mid = vec[vec.size() / 2];
Run Code Online (Sandbox Code Playgroud)

  • 至少可以说,在这里使用`at`是非正统的.在目前的情况下,*永远不会*成为访问错误,为什么要防范呢? (3认同)

Hen*_*rik 22

您无法添加迭代器.你可以做什么:

vector<int>::iterator mid = ivec.begin() + distance(ivec.begin(), ivec.end()) / 2;
Run Code Online (Sandbox Code Playgroud)

  • @PeterWood - 在这种情况下,是的.但距离也适用于其他容器,而不仅仅是矢量. (3认同)

bit*_*ask 7

它只是意味着vector迭代器没有加法运算符(+).你不能添加ivec.begin()ivec.end().

要获取中间元素,您只需使用下标运算符:

cout << ivec[ivec.size()/2] << endl;
Run Code Online (Sandbox Code Playgroud)

如果你坚持使用迭代器,你可以得到一个以这种方式指向中间的迭代器:

vector<int>::iterator mid = ivec.begin();
mid += ivec.size()/2;
cout << *mid << endl;
Run Code Online (Sandbox Code Playgroud)

你可以这样做,因为vector迭代器是一个随机访问迭代器(在所有实现中我都知道它封装了一个指向原始容器数据的实际指针).


luk*_*uke 6

您无法添加迭代器.

你想要使用的是std :: distance()std :: advance()的组合:

vector<int>::iterator mid = std::advance(ivec.begin(), std::distance(ivec.begin(), ivec.end()) / 2);
Run Code Online (Sandbox Code Playgroud)

为什么要使用std::advance()迭代器的加法运算符呢? std::advance()无论迭代器类型如何(随机访问,仅向前,双向等)都可以最佳地工作,因此如果切换std::vectorstd::list上面的代码可以保持不变,并且仍然可以最佳地工作.