Что означает ошибка, когда я компилирую С++ с компилятором g++?
используя следующий код:
#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() не может использоваться как обычный векторный элемент. Но я не могу понять, что означает информация об ошибке... что-то о operator +?
Ответы
Ответ 1
Вы не можете добавить два итератора вместе.
operator+
не определен для двух итераторов, потому что эта операция не имеет смысла. Итераторы - это своего рода обобщение по указателям - они указывают на конкретный элемент, хранящийся в контейнере. В каком элементе указывается сумма итераторов?
Однако, когда вы используете вектор, вы можете добавить целые числа в итераторы, например:
vec.begin() + vec.size() / 2
и поэтому в сообщении об ошибке есть candidates are: (...)
, за которым следуют некоторые определения operator+
.
В вашем случае лучший и самый чистый способ не будет использовать итераторы, но просто получить значение из указанной позиции:
int mid = vec[vec.size() / 2];
Ответ 2
Вы не можете добавлять итераторы. Что вы можете сделать:
vector<int>::iterator mid = ivec.begin() + distance(ivec.begin(), ivec.end()) / 2;
Ответ 3
Это просто означает, что итераторы 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
является итератором произвольного доступа (во всех реализациях, о которых я знаю, он инкапсулирует фактический указатель на необработанные данные контейнера).
Ответ 4
Вы не можете добавлять итераторы.
Что вы хотите использовать, это комбинация std:: distance() и станд:: авансовый():
vector<int>::iterator mid = std::advance(ivec.begin(), std::distance(ivec.begin(), ivec.end()) / 2);
Зачем использовать std::advance()
вместо оператора сложения итератора? std::advance()
работает оптимально независимо от типа итератора (произвольный доступ, только вперед, двунаправленный и т.д.), поэтому, если вы переключаетесь с std::vector
на std::list
, вышеуказанный код может оставаться неизменным и по-прежнему работать оптимально.
Ответ 5
невозможно добавить два итератора
используйте для получения среднего элемента:
ivec.at(ivec.size()/2);
Ответ 6
Вы не можете добавить два итератора вместе, потому что итераторы не являются целыми. Это означает, что это сообщение об ошибке. Если вы хотите получить доступ к элементу в середине вектора, используйте ivec[ivec.size() / 2]
.