что означает ошибка, когда я компилирую c ++ с помощью компилятора g ++? - PullRequest
29 голосов
/ 13 марта 2012

используя следующий код:

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

Я получаю сообщение об ошибке компиляции с помощью 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> >]

Я знаю, что ivec.end () нельзя использовать в качестве обычного векторного элемента. Но я не могу понять, что означает информация об ошибке ... что-то об операторе +?

Ответы [ 6 ]

23 голосов
/ 13 марта 2012

Вы не можете добавить два итератора вместе.

operator+ не определено для двух итераторов, потому что эта операция не имеет смысла. Итераторы являются своего рода обобщением указателей - они указывают на конкретный элемент, хранящийся в контейнере. На какой элемент указывает сумма итераторов?

Однако, когда вы используете вектор, вы можете добавить целых чисел к итераторам , например:

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

и именно поэтому в вашем сообщении об ошибке есть candidates are: (...), за которым следуют некоторые определения operator+.

В вашем случае лучшим и самым чистым способом будет не использование итераторов, а простой получение значения из указанной позиции :

int mid = vec[vec.size() / 2];
22 голосов
/ 13 марта 2012

Вы не можете добавлять итераторы.Что вы можете сделать:

vector<int>::iterator mid = ivec.begin() + distance(ivec.begin(), ivec.end()) / 2;
7 голосов
/ 13 марта 2012

Это просто означает, что итераторы 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 является итератором с произвольным доступом (во всех известных мне реализациях он инкапсулирует фактический указатель на необработанные данные контейнера).

6 голосов
/ 13 марта 2012

Вы не можете добавлять итераторы.

То, что вы хотите использовать, это комбинация 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 приведенный выше код может остаться прежним и работать оптимально.

3 голосов
/ 13 марта 2012

невозможно добавить два итератора.

используется для получения среднего элемента:

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

2 голосов
/ 13 марта 2012

Нельзя добавить два итератора вместе, потому что итераторы не являются целыми числами.Вот что означает сообщение об ошибке.Если вы хотите получить доступ к элементу в середине вектора, используйте ivec[ivec.size() / 2].

...