29 votes

que signifie l'erreur lorsque je compile c++ avec le compilateur g++ ?

En utilisant le code suivant :

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

J'obtiens une erreur en compilant avec 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> >]

Je sais que le ivec.end() ne peut pas être utilisé comme un élément vectoriel normal. Mais je n'arrive pas à comprendre ce que signifie l'information d'erreur... quelque chose à propos de operator+ ?

23voto

Rafał Rawicki Points 10069

Vous ne peut pas ajouter deux itérateurs ensemble.

operator+ n'est pas défini pour deux itérateurs, car cette opération n'aurait pas de sens. Les itérateurs sont une sorte de généralisation des pointeurs - ils pointent vers l'élément spécifique stocké dans le conteneur. Vers quel élément la somme des itérateurs pointe-t-elle ?

Cependant, lorsque vous utilisez un vecteur, vous pouvez ajouter des entiers aux itérateurs comme ça :

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

et c'est pourquoi vous avez candidates are: (...) dans votre message d'erreur, suivi de quelques définitions de operator+ .

Dans votre cas, la meilleure façon, et la plus propre, sera de ne pas utiliser les itérateurs, mais de simples obtenir la valeur de la position spécifiée :

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

22voto

Henrik Points 16565

Vous ne pouvez pas ajouter des itérateurs. Ce que vous pouvez faire :

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

7voto

bitmask Points 11086

Cela signifie simplement que vector les itérateurs n'ont pas d'opérateur d'addition ( + ). Vous ne pouvez pas ajouter ivec.begin() et ivec.end() .

Pour obtenir l'élément du milieu, vous pouvez simplement utiliser l'opérateur d'indice :

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

Si vous insistez pour utiliser un itérateur, vous pouvez obtenir un itérateur qui pointe vers le milieu de cette manière :

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

Vous pouvez le faire, car le vector iterator est un itérateur à accès aléatoire (dans toutes les implémentations que je connais, il encapsule un pointeur réel vers les données brutes du conteneur).

6voto

luke Points 16255

Vous ne pouvez pas ajouter des itérateurs.

Ce que vous devez utiliser, c'est une combinaison des éléments suivants std::distance() et std::advance() :

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

Pourquoi utiliser std::advance() au lieu de l'opérateur d'addition de l'itérateur ? std::advance() fonctionne de manière optimale, quel que soit le type d'itérateur (accès aléatoire, vers l'avant uniquement, bidirectionnel, etc. std::vector à std::list le code ci-dessus peut rester le même, et continuer à fonctionner de manière optimale.

3voto

Stefan Birladeanu Points 284

Pas possible d'ajouter deux itérateurs

utilisez at pour obtenir l'élément du milieu :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X