 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Franck Branjonneau Guest
|
Posted: Wed Sep 13, 2006 4:18 am Post subject: Re: std::vector |
|
|
loufoque <loufoque (AT) remove (DOT) gmail.com> écrivait:
| Quote: | Jean-Marc Bourguet a écrit :
void f(std::vector<CPoint>& points);
Avec un const généralement
|
Pas ici puisque la fonction originelle demandait un objet mutable, non ?
--
Franck Branjonneau |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Wed Sep 13, 2006 5:16 am Post subject: Re: std::vector |
|
|
Franck Branjonneau wrote on 13/09/2006 01:14:
| Quote: | JM <nospamjm (AT) yahoo (DOT) com> écrivait:
Jean-Marc Bourguet a écrit :
void f(std::vector<CPoint>& points);
Bé d'abord parce que je découvre la STL, ensuite cela m'évite de tout
changer dans un premier temps, puis cela fait des déclarations à
rallonge )
Tu écris :
inline void f(std::vector<CPoint>& points) { return f(&points[0]); }
|
tu plaisantes ?
| Quote: | Quoique avec mon typedef cela devrait pouvoir s'arranger
Quel typedef ?
|
je parie 5 cents sur:
typedef std::vector<CPoint> VPoints;
puis
void f(VPoints& points)
Sylvain. |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Wed Sep 13, 2006 5:18 am Post subject: Re: std::vector |
|
|
Franck Branjonneau wrote on 13/09/2006 01:17:
| Quote: |
Si cela fonctionne, ce n'est que le fruit du hasard (des choix de ton
implémentation) : std::vector<>::begin() retourne un iterateur.
|
c'est quoi un "iterateur" (ça se (s'auto) définit comment? quels sont
ses propres opérateurs de cast?)
Rm: ça retourne un "iterateur" ou un "iterateur const".
Sylvain. |
|
| Back to top |
|
 |
loufoque Guest
|
Posted: Wed Sep 13, 2006 6:30 am Post subject: Re: std::vector |
|
|
Franck Branjonneau a écrit :
| Quote: | Pas ici puisque la fonction originelle demandait un objet mutable, non ?
|
En effet, mais il est possible qu'il n'avait pas besoin d'être mutable,
comme c'est souvent le cas [1], et que const n'avait pas été utilisé car
l'OP ne programmait pas de manière const-correcte.
[1] D'où le /généralement/ du message précédent, le passage par
const-référence étant très souvent utilisé comme alternative à la copie |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 9:11 am Post subject: Re: std::vector |
|
|
Sylvain wrote:
| Quote: | Franck Branjonneau wrote on 13/09/2006 01:17:
Si cela fonctionne, ce n'est que le fruit du hasard (des
choix de ton implémentation) : std::vector<>::begin()
retourne un iterateur.
c'est quoi un "iterateur"
|
Un type qui remplit certaines conditions. Typiquement, c'est une
classe, soit définit (ici) dans std::vector, soit définit
ailleurs, avec un typedef dans std::vector. Donc, par exemple,
avec ton code, VC++ 2005 me dit « cannot convert from
'std::_Vector_iterator<_Ty,_Alloc>' to 'CPoint*', et g++ me dit
« cannot convert
'__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<CPoint*,
__gnu_norm::vector<CPoint, std::allocator<CPoint> > >,
__gnu_debug_def::vector<CPoint, std::allocator<CPoint> > >' to
'CPoint*' ».
Dans d'anciennes implémentations, dans le cas précis de
std::vector (mais non pour les autres collections), c'était un
typedef à un pointeur. Ce qui est permis par la norme, mais ce
qui n'est que rarement le cas dans les implémentations modernes.
| Quote: | (ça se (s'auto) définit comment?
|
C'est défini pour tout collection dans la STL. Le concepte
d'itérateur, d'ailleurs, est vraiment à la base de la STL. Je ne
crois pas qu'on puisse parler de la STL sans le connaître.
| Quote: | quels sont ses propres opérateurs de cast?)
Rm: ça retourne un "iterateur" ou un "iterateur const".
|
Selon le cas, begin renvoie iterator ou const_iterator. (Ou plus
exactement std::container<type>::iterator ou
std::container<type::const_iterator -- dans le cas qui nous
intéresse, donc, std::vector< CPoint >::iterator ou
std::vector< CPoint »:const_iterator. Qui peut être un
typedef -- c'est le cas et avec VC++ et avec g++.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 9:11 am Post subject: Re: std::vector |
|
|
Sylvain wrote:
| Quote: | JM wrote on 12/09/2006 19:57:
void f(std::vector<CPoint>& points);
qui est la forme à laquelle on s'attend si on utilise la
SL.
Bé d'abord parce que je découvre la STL, ensuite cela
m'évite de tout changer dans un premier temps, puis cela
fait des déclarations à rallonge ) Quoique avec mon
typedef cela devrait pouvoir s'arranger
typedef peut aider si tu t'obliges à changer tes interfaces,
cela risque de ne pas tout régler si tu utilises des libs
externes attendant un CPoint*
|
Si c'est une classe à lui, il a toutes les chances à avoir accès
à toutes les fonctions concernées.
| Quote: | au typedef, je préfère généralement l'hétitage avec ajout
d'operateurs de cast, soit ...
|
C'est sûr que je n'aime pas particulièrement le typedef ici.
La façon naturelle en C++ de passer un paramètre par référence,
c'est d'utiliser une référence. Si on a un problème avec des
bibliothèques externe, on le résoud en général avec un wrapper
(modèle décorateur) qui fait les conversions nécessaires.
| Quote: | class Points : public vector<CPoint> {
|
Ce n'est pas en général une bonne idée d'hériter de std::vector.
Il n'a pas été conçu pour servir de classe de base.
| Quote: | public:
Points(){}
operator CPoint* () { return begin(); }
|
Et ça, évidemment, ne se compile pas, sinon que par hazard avec
un ancien compilateur. (Il se compilait avec VC++ 6.0 ou g++
2.95.2, mais il ne se compile pas avec VC++ 2005 ni avec g++
4.1.0.)
| Quote: | operator const CPoint* () const { return begin(); }
|
Pareil.
| Quote: | };
qui permet les déclarations:
void f(CPoint* pts) {}
void g(const CPoint* pts) {}
Points ptTab;
f(ptTab);
g(ptTab);
|
Et qui permet aussi :
std::vector< CPoint >* pv = new Points ;
delete pv ; // Comportement indéfini.
Mais vu que le code ne se compile pas avec un compilateur
moderne (et n'a jamais été légal), qu'importe.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 9:11 am Post subject: Re: std::vector |
|
|
JM wrote:
| Quote: | Jean-Marc Bourguet a écrit :
Normal, mais pourquoi f n'est-elle pas déclarée:
void f(std::vector<CPoint>& points);
qui est la forme à laquelle on s'attend si on utilise la SL.
Bé d'abord parce que je découvre la STL,
|
Au fond, ce que conseille Jean-Marc n'a rien à faire avec la
bibliothèque standard. En général, en C++, si tu veux qu'un
paramètre d'une fonction ait une sémantique de référence, tu
utilises une référence ; si tu veux une sémantique de valeur,
tu passes par valeur, quitte à optimiser avec une référence
const dans le cas où la copie est très chère (souvent le cas
avec std::vector) et que tu ne modifies pas le paramètre dans la
fonction.
Historiquement, tu te trouves dans la situation C, où les
paramètres se passent uniquement par valeur, MAIS où les
tableaux n'étaient pas des types comme les autres. Tandis qu'un
std::vector est un type comme n'importe quel autre type, sans
règles spéciales abhérantes et bizarres.
| Quote: | ensuite cela m'évite de tout changer dans un premier temps,
puis cela fait des déclarations à rallonge )
|
Si tu changes le type d'un paramètre, il faut bien changer la
déclaration des fonctions qui le prend, non ? Sinon, je dirais
qu'il y a un vrai problème.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Sep 13, 2006 5:00 pm Post subject: Re: std::vector |
|
|
On Wed, 13 Sep 2006 13:49:50 +0200, JM <nospamjm (AT) yahoo (DOT) com>:
| Quote: | class Points : public vector<CPoint> {
Ce n'est pas en général une bonne idée d'hériter de std::vector.
Il n'a pas été conçu pour servir de classe de base.
Oui mais si ça marche,
|
Ça marche parfois. |
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Wed Sep 13, 2006 10:37 pm Post subject: Re: std::vector |
|
|
Sylvain <noSpam (AT) mail (DOT) net> écrivait:
| Quote: | Franck Branjonneau wrote on 13/09/2006 01:14:
void f(std::vector<CPoint>& points);
Bé d'abord parce que je découvre la STL, ensuite cela m'évite de tout
changer dans un premier temps, puis cela fait des déclarations à
rallonge )
inline void f(std::vector<CPoint>& points) { return f(&points[0]); }
tu plaisantes ?
|
Non, pourquoi ?
--
Franck Branjonneau |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 10:40 pm Post subject: Re: std::vector |
|
|
JM wrote:
| Quote: | kanze a écrit :
class Points : public vector<CPoint> {
Ce n'est pas en général une bonne idée d'hériter de std::vector.
Il n'a pas été conçu pour servir de classe de base.
Oui mais si ça marche, j'avoue que c'est le principal.
|
Pour quelle définition de marcher ? C'est un piège à con pour
celui qui te suit.
| Quote: | Respecter la norme pour la norme, ce n'est pas mon truc.
|
La norme n'en dit rien ici. C'est plutôt du bon sens qui parle.
| Quote: | En un truc qui la respecte à la lettre, et un autre un peu
moins mais valable et plus lisible, mon choix est vite fait.
|
Le problème, c'est justement que ce genre d'héritage nuit
énormement à la lisibilité. (Les conversions implicites aussi,
évidemment. Peut-être même plus.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 13, 2006 10:43 pm Post subject: Re: std::vector |
|
|
JM wrote:
| Quote: | kanze a écrit :
Si tu changes le type d'un paramètre, il faut bien changer la
déclaration des fonctions qui le prend, non ? Sinon, je dirais
qu'il y a un vrai problème.
Jusqu'à présent, quand je définissais des tableaux, j'utilisais toujours
des trucs du genre :
A machin[NB_MAX]
f(A *pmachin);
Puis j'appelais de la manière suivante : f(machin);
En gros.
Pourquoi?
Parce que j'avais appris comme ça il y a trèèèèèès longtemps.
|
Et tu as appris comme ça parce que c'est comme ça qu'on fait en
C, parce qu'en C, les tableaux, c'est bien des types deuxième
classe.
En C++, on a une meilleur alternative.
| Quote: | Pendant longtemps j'ai eu la flemme d'apprendre la STL, mon
projet initial ne devant pas prendre tant d'ampleur.
Donc je déclarais les tableaux à l'ancienne, mais maintenant,
j'estime que dans un programme moderne, si on limite de
manière définitive la taille des tableaux (par exemple des
tableaux de divers objets graphiques), pour l'utilisateur
c'est trop contraignant.
D'où passage à la STL qui permet de s'affranchir de ça et de
gérer plus facilement la mémoire.
Donc, dans un premier temps, j'essaie de modifier le moins de
chose (en gros, uniquement les déclaration quand c'est
possible) en essayant de réutiliser l'existant.
Si je modifie tout d'un coup, c'est le plantage assuré
|
Et si tu ne le fait pas, ça ne va pas compiler.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Thu Sep 14, 2006 12:52 am Post subject: Re: std::vector |
|
|
Franck Branjonneau wrote on 13/09/2006 19:37:
| Quote: | Sylvain <noSpam (AT) mail (DOT) net> écrivait:
Franck Branjonneau wrote on 13/09/2006 01:14:
void f(std::vector<CPoint>& points);
Bé d'abord parce que je découvre la STL, ensuite cela m'évite de tout
changer dans un premier temps, puis cela fait des déclarations à
rallonge )
inline void f(std::vector<CPoint>& points) { return f(&points[0]); }
tu plaisantes ?
Non, pourquoi ?
|
pour rien.
je ne suis pas payé au caractère, ça doit m'empêcher d'apprécier.
Sylvain. |
|
| Back to top |
|
 |
Cyrille Guest
|
Posted: Thu Sep 14, 2006 1:22 am Post subject: Re: std::vector |
|
|
Sylvain a écrit :
| Quote: | Franck Branjonneau wrote on 13/09/2006 19:37:
Sylvain <noSpam (AT) mail (DOT) net> écrivait:
Franck Branjonneau wrote on 13/09/2006 01:14:
void f(std::vector<CPoint>& points);
Bé d'abord parce que je découvre la STL, ensuite cela m'évite de tout
changer dans un premier temps, puis cela fait des déclarations à
rallonge )
inline void f(std::vector<CPoint>& points) { return f(&points[0]); }
tu plaisantes ?
Non, pourquoi ?
pour rien.
je ne suis pas payé au caractère, ça doit m'empêcher d'apprécier.
|
Euh, ça permet justement d'économiser les efforts en évitant d'avoir à
modifier le code existant... Et d'économiser des caractères si f est
appelé relativement souvent.
--
Les lois sont toujours utiles à ceux qui possèdent et nuisibles à ceux
qui n'ont rien. ~ Rousseau, du Contrat Social. |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Thu Sep 14, 2006 1:45 am Post subject: Re: std::vector |
|
|
kanze wrote on 13/09/2006 10:40:
| Quote: |
typedef peut aider si tu t'obliges à changer tes interfaces,
cela risque de ne pas tout régler si tu utilises des libs
externes attendant un CPoint*
Si c'est une classe à lui, il a toutes les chances à avoir accès
à toutes les fonctions concernées.
|
soit, mais cela peut être la classe (archi basic) des MFC ...
| Quote: | La façon naturelle en C++ de passer un paramètre par référence,
c'est d'utiliser une référence. Si on a un problème avec des
bibliothèques externe, on le résoud en général avec un wrapper
(modèle décorateur) qui fait les conversions nécessaires.
|
si l'objet décoré est le vector<> et si le decorator est celui
qui fournit un opérateur de cast vers CPoint*, le problème
restera identique: obtenir ce pointeur depuis le vector<>.
| Quote: | class Points : public vector<CPoint> {
Ce n'est pas en général une bonne idée d'hériter de std::vector.
Il n'a pas été conçu pour servir de classe de base.
|
cela est propre à vector ou est vrai pour la plupart des classes
templates de la STL ?
| Quote: | public:
Points(){}
operator CPoint* () { return begin(); }
Et ça, évidemment, ne se compile pas, sinon que par hazard avec
un ancien compilateur. (Il se compilait avec VC++ 6.0 ou g++
2.95.2, mais il ne se compile pas avec VC++ 2005 ni avec g++
4.1.0.)
|
le "hasard" est ici simplement la définition des libs fournies
avec les compilo cités, c'est assez déterministe comme hasard.
btw, l'environnement de dév. "Studio" est en version 2005,
les outils C++ (le "produit") sont en version 8, le compilo
(le "fichier" compiler) en version 14.
le problème connu comme "ne se compile pas" est lié à la
version de la STL utilisé, non à celle du compilateur;
dès lors indiquer que cela ne peut fonctionner avec telle
version de la STL, même si cela pouvait être valide avec
telle autre version serait plus instructif.
cela posant d'ailleurs le problème de l'identification de
la version de la STL utilisée, comment la connaitre ?
(j'ai noté un copyright en commentaire en fin de ses
fichiers, ce n'est pas vraiment la réponse attendue).
cela interroge également sur la compatibilité ascendante
des STL, n'étant pas adepte du hasard, comment celle-ci
est garantie ?
plus généralement, existe-t-il une définition normative
des API (donc hors implémentation) qu'une librairie dite
STL doit satisfaire ?
pour revenir sur le fond de ma proposition, que je
reformule en: "est-il possible de changer une déclaration
a-la-mano (new CPoints, etc) par une utilsation de vector<>
*sans* devoir modifier toutes ses procédures de traitement ?"
- je pense inintéressant de savoir si "begin()" se compile
ou si "return &at(0);" est mieux; on codera cet opérateur
une seule et unique fois, il peut changer, j'ai pu donner
un mauvais nom, on s'en tape
- car le point est bcp plus:
* vector<> jouant (déjà) un role de décorateur:
peux-t-on attendre d'une prochaine version (Cf post de
Marc) la disponibilité d'un tel opérateur de cast ?
* ce cast n'étant pas présent aujourd'hui, peut-on malgré
tout supposer un stockage linéaire et continu des éléments
du vector<T> ? (si ce n'est pas le cas, un pointeur T* est
inutilisable et les joyeux iterators obligeatoires)
* dans le même temps s'il est présent, les opérateurs []
vont devenir confus.
| Quote: | operator const CPoint* () const { return begin(); }
Pareil.
|
oui, pareil, il suffit d'utiliser &at(0), n'importe quel
developpeur sait le faire.
| Quote: | Et qui permet aussi :
std::vector< CPoint >* pv = new Points ;
delete pv ; // Comportement indéfini.
|
indéfini parce que vector<> ne définit pas son destructeur
comme virtuel; tu l'as déjà indiqué "Il n'a pas été conçu
pour servir de classe de base."
je m'interroge ici aussi sur ce choix.
| Quote: | Mais vu que le code ne se compile pas avec un compilateur
moderne (et n'a jamais été légal), qu'importe.
|
sur le fond, je suis d'accord avec toi, "qu'importe" de savoir
si begin, pop_truc ou push_machin se compile, ce n'était pas
la question. qu'importe également de savoir si tu fais exprès
de commenter à coté ou si le point n'était pas suffisamment
clair pour toi.
la question qui reste est: peux-t-on accéder linéairement
aux élements d'un vector (ou vector<> peut-il un decorator)?
tu n'as pas éclairé ma lanterne sur ce point.
Sylvain. |
|
| Back to top |
|
 |
Arnaud Debaene Guest
|
Posted: Thu Sep 14, 2006 1:54 am Post subject: Re: std::vector |
|
|
"JM" <nospamjm (AT) yahoo (DOT) com> a écrit dans le message de news:
4507f054$0$25915$ba4acef3 (AT) news (DOT) orange.fr...
| Quote: |
kanze a écrit :
class Points : public vector<CPoint> {
Ce n'est pas en général une bonne idée d'hériter de std::vector.
Il n'a pas été conçu pour servir de classe de base.
Oui mais si ça marche, j'avoue que c'est le principal.
Respecter la norme pour la norme, ce n'est pas mon truc.
En un truc qui la respecte à la lettre, et un autre un peu moins mais
valable et plus lisible, mon choix est vite fait.
|
vector<CPoint>* pTbl=new Points();
//.......
delete pTbl;
Ceci ne "marche" pas car le destructeur de Points n'est pas appelé lors du
delete.
Arnaud |
|
| Back to top |
|
 |
Powered by phpBB © 2001, 2006 phpBB Group
|