2013-10-24 2 views
9

following example не компилируется с помощью г ++ 4.8.2:Missing const_iterator перегрузка станд :: вектор :: стиранием() с г ++ 4.8

#include <iostream> 
#include <vector> 
using namespace std; 

int main() { 
    vector<int> v {1, 2, 3}; 

    v.erase(v.cbegin()); // Compiler complains 

    return 0; 
} 

Компилятор говорит следующее. (Это не очень читаемый, но жалуется, что не известное преобразование между vector<int>::const_iterator и vector<int>::iterator.)

prog.cpp: In function ‘int main()’: 
prog.cpp:8:20: error: no matching function for call to ‘std::vector<int>::erase(std::vector<int>::const_iterator)’ 
    v.erase(v.cbegin()); 
        ^
prog.cpp:8:20: note: candidates are: 
In file included from /usr/include/c++/4.8/vector:69:0, 
       from prog.cpp:2: 
/usr/include/c++/4.8/bits/vector.tcc:134:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*] 
    vector<_Tp, _Alloc>:: 
    ^
/usr/include/c++/4.8/bits/vector.tcc:134:5: note: no known conversion for argument 1 from ‘std::vector<int>::const_iterator {aka __gnu_cxx::__normal_iterator<const int*, std::vector<int> >}’ to ‘std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}’ 
/usr/include/c++/4.8/bits/vector.tcc:146:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*] 
    vector<_Tp, _Alloc>:: 
    ^
/usr/include/c++/4.8/bits/vector.tcc:146:5: note: candidate expects 2 arguments, 1 provided 

Почему? В стандарте C++ 11 в §23.3.6.5 говорится, что функция vector::eraseпринимает const_iterator. (Парафраз here и here.)

Что хорошего обходного пути, предполагая, что я должен использовать const_iterator?

+1

Это просто еще не реализовано. – stefan

+0

Это раздражает ... вопрос отредактирован; что хорошего обходного пути? – thirtythreeforty

+0

Обходным решением было бы использовать неконстантные итераторы. – stefan

ответ

12

Это известная ошибка в НКУ: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57158

Стирание требуется итератор вместо const_iterator с нынешних ССЗ.

+1

Хммм. Эта ошибка отмечена дубликатом исправленной ошибки, но для 'deque'. – thirtythreeforty

+2

@thirtythreeforty "Целевая веха: \t 4.9.0« Решено не означает «исправлено в каждой версии». – stefan

+0

@stefan Ой, я понял, я пропустил это. Хорошо. Любые советы по конвертации между двумя, или я должен просто сосать его и использовать инертный неконвертер? – thirtythreeforty

7

Вы можете получить неконстантный итератор с помощью арифметики указателей, здесь вспомогательная функция, чтобы сделать это:

template<typename T> 
    typename std::vector<T>::iterator 
    const_iterator_cast(std::vector<T>& v, typename std::vector<T>::const_iterator iter) 
    { 
    return v.begin() + (iter - v.cbegin()); 
    } 

используется следующим образом:

std::vector<T> v(1); 
auto citer = v.cbegin(); 
v.erase(const_iterator_cast(v, citer)); 
+0

Эта функция работает только для итераторов произвольного доступа .. – rabensky

+0

@rabensky: Попробуйте '' 'return std :: next (v.begin(), std :: distance (v.cbegin(), iter));' ''. – ManuelAtWork

+0

@rabensky, что хорошо, потому что речь идет конкретно о 'std :: vector' и имеет итераторы произвольного доступа. И вспомогательная функция явно принимает аргумент типа 'std :: vector &', поэтому он работает только с 'std :: vector'. –

Смежные вопросы