Problème avec std::vector et std::pair

Résolu
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 - 14 mai 2005 à 18:06
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 - 15 mai 2005 à 01:26
J'ai une fonction qui compilait très bien sous linux, mais pas moyen de
la compiler avec devCpp. Quelqu'un saurait pourquoi il la refuse ?



template <class _U1, class _V1>

std::ostream & operator << (std::ostream & chaine, std::vector<std::pair< _U1, _V1> > & which)

{

std::vector< std::pair< _U1, _V1> >::iterator it; // <=== L'erreur est ici:

// expected `;' before "it"

// `it' undeclared (first use this function)



for (it = which.begin() ; it != which.end() ; it++)

{

chaine << it->first << " = " << it->second << std::endl;

}

return chaine;

}



Il n'y a aucun problème si je déclare ca:

std::vector< std::pair< int, string> >::iterator it;



Donc où est le problème avec les templates et DevCpp ?

8 réponses

steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
14 mai 2005 à 19:35
iterator est un type membre de std::vector, il me semble meme que
d'apres la specification de vector faite par le standard on peu penser
que c'est un alias de T*.

typename std::vector< std::pair< _U1, _V1> >::iterator it;

c'est juste pour indiquer à ton compilo que c'est un type.

Pour le coup ca devrait meme etre un const_iterator.
3
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
14 mai 2005 à 18:47
Moi ca passe avec VC++ et avec MinGW aussi. Juste des warnings avec MinGW:



C:\>g++ test.cpp

test.cpp: In function `std::ostream& operator<<(std::ostream&,

std::vector<std::pair<_T1, _T2>, std::allocator<std::pair<_T1, _T2> > >&)':

test.cpp:6: warning: `typename std::vector<std::pair<_T1, _T2>,

std::allocator<std::pair<_T1, _T2> > >::iterator' is implicitly a typename

test.cpp:6: warning: implicit typename is deprecated, please see the

documentation for details



Tu vois ce que c'est? iterator n'est pas cencé être un namespace mais bien une classe, non?

Ca ne change rien en remplacant les class par des typename (je connais pas la différence entre les deux donc j'essaie)
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
14 mai 2005 à 19:42
Sous VC++ en tous cas j'ai l'impression que c'est une classe (bien que j'ai du mal a lire les sources) qui contient un pointeur
0
steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
14 mai 2005 à 20:40
fais une recherche et positionnes toi au debut de la declaration de la
classe vector, puis a partir de la fait une recherche sur iterator,
etant donnée que le standard garanti que les données d'un vector sont
continues, je suis a peu pres sur que tu dois avoir

template <classe _Tp, ...>

class vector ...

{

typedef _Tp * iterator; // tout simplement, c'est ce que j'ai avec devcpp

}



tu as quoi exactement ?



ps: j'ai déja lu mon implémentation de std::vector, c'est vrai que
c'est rebutant mais en realité ca reste facile à lire par rapport à
d'autres classes de la stl et ca permet vraiment de bien comprendre
comment fonctionne vector.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
14 mai 2005 à 21:50
Il y a quelques typedef mais pas pour les iterator. Je pensais que
c'étaient des classes friend, mais en fait ce sont carrément des
classes internes (comme les inner-class en Java, je savais même pas de
c'était possible en C++).

Voila a quoi ressemble l'implémentation de VC++ pour vector:





// TEMPLATE CLASS vector

template<class _Ty,

class _Ax = allocator<_Ty> >

class vector

: public _Vector_val<_Ty, _Ax>

{ // varying size array of values

public:

typedef vector<_Ty, _Ax> _Myt;



... // QUELQUES TYPEDEFS



#define _ITER_BASE(it) (it)._Myptr

// CLASS const_iterator

class const_iterator;

friend class const_iterator;



class const_iterator {...}

class iterator;

friend class iterator;

class iterator

: public const_iterator

{...}

typedef std::reverse_iterator reverse_iterator;

typedef std::reverse_iterator<const_iterator> const_reverse_iterator;



... //METHODES DE VECTOR
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
14 mai 2005 à 21:53
Impeccable merci beaucoup, en effet rajouter typename devant
std::vector résoue le problème. Mais j'avoue que j'ai du mal a saisir
l'origine de typename. Quand on ouvre stl_vector.h, on trouve la ligne
suivante:



typedef __gnu_cxx::__normal_iterator iterator;



Il faudrait connaitre le fonctionnement de __normal_iterator. Et ca a l'air de se compliquer.
0
steve_clamage Messages postés 475 Date d'inscription dimanche 3 octobre 2004 Statut Membre Dernière intervention 11 août 2006 5
14 mai 2005 à 22:51
__normal_iterator est un adaptateur (adapter) qui permet a priori
d'avoir une certaine interface (c'est un design pattern). En standard
la stl fourni std::reverse_iterator qui esr un adaptateur permettant de
transformer un iterator en reverse_iterator

par exemple

typedef std::reverse_iterator reverse_iterator;

ce qui change c'est (entre autre) que l'operateur ++ de
reverse_iterator fera la meme chose que l'operateur -- d'iterator par
un changement d'interface.



vecchio56, on appel ca des types membres (ou type encapsulé) et c'est
tres important en c++ car c'est le seul moyen de programmer proprement,
il y en a plein la STL.

typedef T* iterator;

ca revient au meme de faire

class iterator {};

dans les deux cas iterator est un type membre de vector



si tu fais une classe qui charge une image bmp et que cette classe agrege un objet de type bmp_header, plutot que de faire

class bmp_header

{

};



class bmp

{

bmp_header _header;

};



il est bien plus raisonnable de faire (car header n'a de raison d'etre que dans bmp)

class bmp


{


class header

{

};

header _header;


};
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
15 mai 2005 à 01:26
Instructif. :)
0
Rejoignez-nous