Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

pb d'itérateur et de fonction membre const

5 réponses
Avatar
Aurélien Barbier-Accary
Bonjour,

J'ai une erreur que je ne comprends pas lorsque j'utilise un itérateur.
Quelqu'un peut-il m'aiguiller ?
Voici les éléments clefs de mon programme :

// Etant donnée une classe définissant un point en 3D
class MPoint3D
{
private:
double x_, y_, z_;

public:
//...
double x(void) const { return x_; }
double y(void) const { return y_; }
double z(void) const { return z_; }

double& x(void) { return x_; }
double& y(void) { return y_; }
double& z(void) { return z_; }
//...
};

// et une classe définissant un tracé (polylignes)
class MDrawing
{
//...
vector<vector<MPoint3D> > inputcurve; // plusieurs polylignes
//...
void displayGL(void) const;
//...
};

// voici une simple fonction d'affichage de la polyligne 0
void MDrawing::displayGL(void) const
{
glBegin(GL_LINES);
for(vector<MPoint3D>::iterator it = inputcurve[0].begin();
it != inputcurve[0].end(); it++)
glVertex3f(it->x(),it->y(),it->z());
glEnd();
}

J'obtiens alors le message d'erreur suivant (g++ 3.4.2) :
D:/.../stl_iterator.h: In constructor
`__gnu_cxx::__normal_iterator<_Iterator,_Container>::__normal_iterator(const
__gnu_cxx::__normal_iterator<_Iter, _Container>&) [with _Iter = const MPoint3D*,
_Iterator = MPoint3D*, _Container = std::vector<MPoint3D,
std::allocator<MPoint3D> >]': mdrawing.cpp:108:
instantiated from here
D:/.../stl_iterator.h:609: error: invalid conversion from `const MPoint3D*
const' to `MPoint3D*'

alors que sans itérateur cela fonctionne :
for(unsigned i=0; i<inputcurve[0].size(); i++)
glVertex3f(inputcurve[0][i].x(),inputcurve[0][i].y(),inputcurve[0][i].z());


Merci pour votre aide.
Aurélien.

5 réponses

Avatar
Gabriel Dos Reis
Aurélien Barbier-Accary writes:

| class MDrawing
| {
| //...
| vector<vector<MPoint3D> > inputcurve; // plusieurs polylignes
| //...
| void displayGL(void) const;
| //...
| };
|
| // voici une simple fonction d'affichage de la polyligne 0
| void MDrawing::displayGL(void) const
^^^^^

| {
| glBegin(GL_LINES);
| for(vector<MPoint3D>::iterator it = inputcurve[0].begin();
^^^

Tu as envie d'écrire

for(vector<MPoint3D>::const_iterator it = inputcurve[0].begin();

J'ai tendance à éviter ces problèmes en laissant le compilateur
déduire les bons types qui vont bien.

struct push_vertex {
void operator()(const MPoint3D& p) const {
glVertex3f(p.x(), p.y(), p.z());
}
};

// ...

std::for_each(inputcurve[0]..begin(), inputcurve[0].end(), push_vertex());

-- Gaby
Avatar
Aurélien Barbier-Accary
Aurélien Barbier-Accary writes:
Tu as envie d'écrire

for(vector<MPoint3D>::const_iterator it = inputcurve[0].begin();



Merci beaucoup !
Effectivement, je viens de découvrir les const_iterator :-)
Bizarre que je n'en ai jamais eu besoin avant.

J'ai tendance à éviter ces problèmes en laissant le compilateur
déduire les bons types qui vont bien.

struct push_vertex {
void operator()(const MPoint3D& p) const {
glVertex3f(p.x(), p.y(), p.z());
}
};

// ...

std::for_each(inputcurve[0]..begin(), inputcurve[0].end(), push_vertex());



Je ne suis pas sûr de bien comprendre l'intérêt. N'est-ce pas trop lourd si on a
besoin de différentes boucles sur ce "vector constant" ? (si bien sûr les
boucles font des traitements différents).
Il est vrai que je n'utilise jamais for_each...

Avatar
Gabriel Dos Reis
Aurélien Barbier-Accary writes:

| > J'ai tendance à éviter ces problèmes en laissant le compilateur
| > déduire les bons types qui vont bien.
| >
| > struct push_vertex {
| > void operator()(const MPoint3D& p) const {
| > glVertex3f(p.x(), p.y(), p.z());
| > }
| > };
| >
| > // ...
| >
| > std::for_each(inputcurve[0]..begin(), inputcurve[0].end(), push_vertex());
| >
|
| Je ne suis pas sûr de bien comprendre l'intérêt.

je crois que je l'ai expliqué dans la phrase qui précède le code :-)

| N'est-ce pas trop lourd si on a
| besoin de différentes boucles sur ce "vector constant" ?

« trop lourd » par rapport à ?

| (si bien sûr les boucles font des traitements différents).

j'utiliserais des objets functionnels différents. Mais encore une
fois, il faut juger dans le contexte et les alternatifs.

-- Gaby
Avatar
Aurélien Barbier-Accary
Aurélien Barbier-Accary writes:

| > J'ai tendance à éviter ces problèmes en laissant le compilateur
| > déduire les bons types qui vont bien.
|
| Je ne suis pas sûr de bien comprendre l'intérêt.

je crois que je l'ai expliqué dans la phrase qui précède le code :-)

| N'est-ce pas trop lourd si on a
| besoin de différentes boucles sur ce "vector constant" ?

« trop lourd » par rapport à ?

| (si bien sûr les boucles font des traitements différents).

j'utiliserais des objets functionnels différents. Mais encore une
fois, il faut juger dans le contexte et les alternatifs.



oui je me suis mal exprimé :-)
Ce que je voulais dire c'est que quand on connaît les const_iterator :-p il me
parait finalement plus simple (moins lourd en terme de code, de complexité
apparente) de les utiliser plutôt que de définir un objet fonctionnel pour
chaque boucle.
Mais il s'agit sans doute simplement d'habitudes de travail différentes...
En tous cas merci de m'offrir cette ouverture vers une autre alternative et bien
sûr de m'avoir fait connaître les const_iterator.
Aurélien.

Avatar
kanze
Aurélien Barbier-Accary wrote:

[...]
J'ai tendance à éviter ces problèmes en laissant le
compilateur déduire les bons types qui vont bien.

struct push_vertex {
void operator()(const MPoint3D& p) const {
glVertex3f(p.x(), p.y(), p.z());
}
};

// ...

std::for_each(inputcurve[0]..begin(), inputcurve[0].end(), push_vert ex());



Je ne suis pas sûr de bien comprendre l'intérêt. N'est-ce pas
trop lourd si on a besoin de différentes boucles sur ce
"vector constant" ? (si bien sûr les


Tout dépend. for_each a l'avantage de dire que tu effectues le
traitement sur tous les éléments, toujours -- avec le for, il
faut bien vérifier qu'il n'y a pas de break ou autre chose.

Si l'opération s'exprime d'une façon aussi simple que si dessus,
j'ai une tendance à préférer le for_each. Si, en revanche
glVertex2f est une fonction member, et qu'il faut ajouter un
constructeur à push_vertex, qui prend un pointeur à l'objet, et
éventuellement rendre l'objet ami, parce que glVertex2f est
privé, ou d'autres choses de ce genre, ça devient moins
intéressant.

boucles font des traitements différents).
Il est vrai que je n'utilise jamais for_each...


D'un certain égard, c'est le moins intéressant des algorithmes
standard, simplement parce que son nom dit le moins ce qu'il
fait (parce qu'il fait moins, évidemment). L'expression du fait
qu'on visite toujours tous les objets, inconditionnellement,
peut être utile cependant pour celui qui lit le programme. À
condition de ne pas introduire d'autres difficultés de lecture
par ailleurs, évidemment.

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