2012-03-13 129 views
29

使用以下代码:当我用g ++编译器编译C++时,错误是什么意思?

#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; 
} 

获得带有克++编译一个错误:

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> >] 

我知道ivec.end()不能被用作通常的向量元素。但我不明白什么是错误信息意味着...关于operator +的一些东西?

+9

对于一个问题很好,格式良好,标记正确的第一个问题,+1。 – razlebe 2012-03-13 13:26:32

+8

+1包括一个简短的完整样本程序。 http://sscce.org/ – 2012-03-13 13:28:15

回答

23

不能添加两个迭代在一起。

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

但是,当您使用矢量,你可以添加整数迭代,这样的:

vec.begin() + vec.size()/2 

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

在你的情况是最好的,最彻底的方法将不使用迭代器,但简单从指定位置所获得的价值:

int mid = vec[vec.size()/2]; 
+3

这里使用'at'是非正统的,至少可以说。在目前的情况下,可能永远不会出现访问错误,那么为什么要防范呢? – 2012-03-13 19:05:46

+0

我同意,'at()'改为'[]'。 – 2012-03-13 21:40:57

2

您不能添加两个迭代在一起,因为迭代不是整数。这就是错误信息的含义。如果要访问矢量中间的元素,请使用ivec[ivec.size()/2]

7

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

要获得中间元素,你可以简单地使用下标操作符:

cout << ivec[ivec.size()/2] << endl; 

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

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

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

+0

在诸如MSVC的许多调试版本中,'vector :: iterator'也包含数组边界。这意味着它将在调试中捕获大部分界限错误。 – MSalters 2012-03-13 14:36:44

+0

@ MSalters:是的,但我的观点是,它也包含指向原始序列(数组)的指针。 – bitmask 2012-03-13 14:37:54

22

您不能添加迭代器。你可以做什么:

vector<int>::iterator mid = ivec.begin() + distance(ivec.begin(), ivec.end())/2; 
+4

+1使用std :: distance() – ComicSansMS 2012-03-13 13:36:28

+0

'distance(vector :: begin,vector :: end)'不会与'vector :: size'相同吗? – 2012-03-13 13:50:11

+3

@PeterWood - 在这种情况下,是的。但距离也适用于其他容器,而不仅仅是矢量。 – Henrik 2012-03-13 13:52:09

3

不能添加两个迭代

使用在获得中间项:

ivec.at(ivec.size()/ 2);

+0

@亨利克:缺乏背景。这将会:'cout << ivec.at(ivec.size()/ 2)<< endl;'。如果你知道'ivec'不是空的,你也可以写'cout << ivec [ivec.size()/ 2] << endl;' – MSalters 2012-03-13 14:40:15

6

不能添加迭代器。

什么,你需要使用是std::distance()std::advance()组合:

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

为什么使用std::advance(),而不是迭代器的加法运算符? std::advance()无论迭代类型如何(随机访问,只转发,双向等)都能以最佳方式工作,所以如果您从std::vector切换到std::list,上面的代码可以保持不变,并仍然以最佳方式工作。

+0

这不再适用于'std :: list'。在C++ 11中,'std :: distance(ilist.begin(),ilist.end())'仍然可以是O(N),但是'ilist.size()'在O(1)中返回相同的值。 – MSalters 2012-03-13 14:34:41

+0

@ MSalters:有趣!为什么要改变? – luke 2012-03-13 14:55:08

+0

C++ 03允许这两者,并在'splice'上进行必要的权衡。因此,可移植代码必须将'size'和'splice'都视为O(N)。 C++ 11可移植地生成了“大小”O(1)。 – MSalters 2012-03-15 10:14:26

相关问题