2012-03-13 126 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

相關問題