OVH Cloud OVH Cloud

std::vector

25 réponses
Avatar
JM
Bonjour

J'ai enfin décidé de me modernisé et d'utiliser la STl pour la gestion
des tableaux (ne pas s'occuper de l'allocation, c'est bien sympathique)

voilà, j'ai un truc du genre :

1) sans STL

void f(CPoint *points);

CPoint ptTab[NBMAX]

L'appel f(ptTab) marche sans problème.

Avec la STl, je crée :

vector<CPoint> ptTab;


Si je fais f(ptTab) ça marche pas
Le seul truc que j'ai réussi à faire marcher est f(&ptTab[0])

Est-ce normal où ai-je raté quelque chose?

Merci

10 réponses

1 2 3
Avatar
Marc Boyer
Le 12-09-2006, JM a écrit :
Bonjour

J'ai enfin décidé de me modernisé et d'utiliser la STl pour la gestion
des tableaux (ne pas s'occuper de l'allocation, c'est bien sympathique)

voilà, j'ai un truc du genre :

1) sans STL

void f(CPoint *points);

CPoint ptTab[NBMAX]

L'appel f(ptTab) marche sans problème.


Normal.

Avec la STl, je crée :

vector<CPoint> ptTab;

Si je fais f(ptTab) ça marche pas


Normal (ce sont des types différents).

Le seul truc que j'ai réussi à faire marcher est f(&ptTab[0])


C'est un truc tellement naturel et courant que beaucoup
s'attendent à ce que la prochaine révision de la norme
le standardise/

Est-ce normal où ai-je raté quelque chose?


Non, tout m'a l'air normal.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
JM

Le seul truc que j'ai réussi à faire marcher est f(&ptTab[0])


C'est un truc tellement naturel et courant que beaucoup
s'attendent à ce que la prochaine révision de la norme
le standardise/


Ah?
Bon, il faudra que j'en prenne l'habitude.

Une nouvelle fois merci :)


Avatar
Jean-Marc Bourguet
JM writes:

Le seul truc que j'ai réussi à faire marcher est f(&ptTab[0])

Est-ce normal où ai-je raté quelque chose?


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.

Au fait, comme toujours avec les pointeurs il faut faire
attention à la durée de vie de ceux-ci. Si tu modifies la
taille de ptTab (qui est par ailleurs mal nommé), le
pointeur que tu as optenu peut être invalidé.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
JM

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, ensuite cela m'évite de tout
changer dans un premier temps, puis cela fait des déclarations à
rallonge :o)
Quoique avec mon typedef cela devrait pouvoir s'arranger

Au fait, comme toujours avec les pointeurs il faut faire
attention à la durée de vie de ceux-ci. Si tu modifies la
taille de ptTab (qui est par ailleurs mal nommé), le
pointeur que tu as optenu peut être invalidé.


Effectivement, je n'y avais pas pensé, d'où l'intérêt de la déclaration
que tu donnes.

Merci

Avatar
Sylvain
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 :o)
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*

au typedef, je préfère généralement l'hétitage avec ajout d'operateurs
de cast, soit ...

class Points : public vector<CPoint> {
public:
Points(){}
operator CPoint* () { return begin(); }
operator const CPoint* () const { return begin(); }
};

qui permet les déclarations:

void f(CPoint* pts) {}
void g(const CPoint* pts) {}

Points ptTab;
f(ptTab);
g(ptTab);

soit une utilisation directe de tes codes sans la moindre modif
(expectée la déclaration initiale et son allocation qui t'embêtait).

Sylvain.


Avatar
loufoque

void f(std::vector<CPoint>& points);


Avec un const généralement

Avatar
Franck Branjonneau
JM écrivait:


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 :o)


Tu écris :

inline void f(std::vector<CPoint>& points) { return f(&points[0]); }

Quoique avec mon typedef cela devrait pouvoir s'arranger


Quel typedef ?

--
Franck Branjonneau


Avatar
Franck Branjonneau
Sylvain écrivait:

au typedef, je préfère généralement l'hétitage avec ajout d'operateurs
de cast, soit ...

class Points : public vector<CPoint> {
public:
Points(){}
operator CPoint* () { return begin(); }
operator const CPoint* () const { return begin(); }
};


Si cela fonctionne, ce n'est que le fruit du hasard (des choix de ton
implémentation) : std::vector<>::begin() retourne un iterateur.

--
Franck Branjonneau

Avatar
Franck Branjonneau
loufoque écrivait:


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


Avatar
kanze
Sylvain wrote:
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 :o) 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.

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.

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.

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.)

operator const CPoint* () const { return begin(); }


Pareil.

};

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



1 2 3