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

Utiliser les algorithmes STL sur un conteneur de pointeurs

10 réponses
Avatar
Pierre THIERRY
J'ai un petit problème dont je me dis qu'il doit être courant : j'ai un
conteneur STL de pointeurs, et j'aimerais utiliser l'algo accumulate sur
les objets pointés. Donc il me faudrait, a priori, un itérateur
adapatateur, qui déréférence le pointeur qu'on obtient en déréférençant
l'itérateur de base.

Je n'ai rien trouvé par Google (pas de mots-clef probants, peut-êre),
mais je me dis que le problème a déjà du être rencontré pléthores de
fois. S'il y a une implémentation de référence, élégante et robuste, je
suis preneur...

Brièvement,
Nowhere man
--
nowhere.man@levallois.eu.org
OpenPGP 0xD9D50D8A

10 réponses

Avatar
Etienne Rousee
"Pierre THIERRY" ...
J'ai un petit problème dont je me dis qu'il doit être courant : j'ai un
conteneur STL de pointeurs, et j'aimerais utiliser l'algo accumulate sur
les objets pointés. Donc il me faudrait, a priori, un itérateur
adapatateur, qui déréférence le pointeur qu'on obtient en déréférençant
l'itérateur de base.


Voilà "peut-être" une idée:

Ce n'est pas très satisfaisant, car comment libérer les pointeurs
intermédiaires ? Je suis tenté de rajouter un delete t2 dans l'
operator() de Ajoute, mais l'ordre de parcours est il standard,
et est ce que je suis sûr de détruire ainsi le bon ?

Fichier "Toto.h":
class Toto
{
public:

Toto(int n= 0): _x(n) {}
int getx() { return _x; }
void setx(int n) { _x = n; }

private:

int _x;
};

class Ajoute
{
public:

Toto *operator () (Toto *t1, Toto *t2) const
{
Toto *tmp = new Toto(t1->getx()+t2->getx());

return tmp;
}
};

class Delete
{
public:

template <class T> operator ()(T*& p) const
{
delete p;
p = NULL;
}
};

Fichier "TestAccu.cpp":

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;

#include "Toto.h"

vector <Toto *> v;
Toto Tinit(42),*Tresult;

void Vinit()
{
for (int i = 0; i < 10; i++)
{
Toto *T = new Toto(i * i);
v.push_back(T);
}
}


int main (void)
{
Vinit();

Tresult = accumulate(v.begin(),v.end(),&Tinit,Ajoute());

cout << Tresult->getx() << endl;

for_each(v.begin(), v.end(), Delete());

return 0;
}

Etienne

Avatar
Etienne Rousee
"Etienne Rousee" a écrit ...
"Pierre THIERRY" ...
J'ai un petit problème dont je me dis qu'il doit être courant : j'ai un
conteneur STL de pointeurs, et j'aimerais utiliser l'algo accumulate sur
les objets pointés. Donc il me faudrait, a priori, un itérateur
adapatateur, qui déréférence le pointeur qu'on obtient en déréférençant
l'itérateur de base.



J'allais chercher bien loin ce qui était simple:

Fichier "Toto.h":

class Toto
{
public:

Toto(int n= 0): _x(n) {}
int getx() { return _x; }
void setx(int n) { _x = n; }

private:

int _x;
};

class Delete
{
public:

template <class T> operator ()(T*& p) const
{
delete p;
p = NULL;
}
};

Fichier "TestAccu.cpp":

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;

#include "Toto.h"

vector <Toto *> v;
int Result, Init = 42;

void Vinit()
{
for (int i = 0; i < 10; i++)
v.push_back(new Toto(i * i)); // par exemple
}

int Ajoute(int val,Toto *T)
{
return val + T->getx(); // ou toute autre fonction d'accès
}

int main(void)
{
Vinit();
Result = accumulate(v.begin(),v.end(),Init,Ajoute);
cout << Result << endl;
for_each(v.begin(), v.end(), Delete());

return 0;
}

Etienne


Avatar
Marc Duflot
Pierre THIERRY wrote:
J'ai un petit problème dont je me dis qu'il doit être courant : j'ai un
conteneur STL de pointeurs, et j'aimerais utiliser l'algo accumulate sur
les objets pointés. Donc il me faudrait, a priori, un itérateur
adapatateur, qui déréférence le pointeur qu'on obtient en déréférençant
l'itérateur de base.


Voila : http://www.boost.org/libs/iterator/doc/indirect_iterator.html

Avatar
Pierre THIERRY
Le Sun, 08 May 2005 18:51:21 +0200, Etienne Rousee a écrit :
J'allais chercher bien loin ce qui était simple:


N'empêche que cet exemple oblige à réécrire tous les foncteurs de la
STL, ce qui n'est pas mon souhait (je dirais même plus, ce que je ne
souhaite pas). Je cherchais plutôt un adaptateur d'itérateur, que je
pourrais utiliser plus ou moins ainsi :

int i;
vector<Foo*> v;
// on remplit v de pointeurs...
dereferencing_iterator< vector<Foo*>::iterator > it1 = v.begin(), it2 = v.begin() + 1;
i = accumulate(it1, it2, 0);

Mais peut-être faudrait-il plutôt que je fasse un template sur le
conteneur :

int i;
dereferencing<vector<Foo*>> v;
// on remplit v de pointeurs...
i = accumulate(it1, it2, 0);

Mais dans ce cas, je perds l'accès aux pointeurs ; d'un autre côté, il
suffit de lui adjoindre un type de pointeur classique :

dereferencing<vector<Foo*>>::pointer_iterator

Et des méthodes fournissant ce type d'itérateur, à la manière de
rbeign() et rend() qui fournissent, dans la STL, des reverse_iterator :

dereferencing<vector<Foo*>>::pbegin()
dereferencing<vector<Foo*>>::pend()

QVEP ?

Projectivement,
Nowhere man
--

OpenPGP 0xD9D50D8A

Avatar
Pierre THIERRY
Le Mon, 09 May 2005 11:10:26 +0200, Marc Duflot a écrit :
Voila : http://www.boost.org/libs/iterator/doc/indirect_iterator.html


HA ! C'est *exactement* ce que je voulais ! C'est nickel, ça marche.
J'ai pu virer ces atroces boucles for pour mettre de beaux et lisibles
algos STL.

Merci infiniment.

Je devrais survoler toute la doc de Boost pour savoir un peu ce qu'il y
dedans. Par contre, cette bibliothèque est assez mal documentée vs-à-vis
de l'utilisateur final. J'ai galéré quelques longues et interminables
minutes pour savoir quel header inclure pour mon adapteur d'itérateur...
Par contre, je sais tout sur les règles à respecter pour soumettre un
module à Boost. :-/

Finalement,
Nowhere man
--

OpenPGP 0xD9D50D8A

Avatar
kanze
Pierre THIERRY wrote:
Voila :
http://www.boost.org/libs/iterator/doc/indirect_iterator.html



HA ! C'est *exactement* ce que je voulais ! C'est nickel, ça
marche. J'ai pu virer ces atroces boucles for pour mettre de
beaux et lisibles algos STL.

Merci infiniment.

Je devrais survoler toute la doc de Boost pour savoir un peu
ce qu'il y dedans. Par contre, cette bibliothèque est assez
mal documentée vs-à-vis de l'utilisateur final.


Par rapport à quoi ? Parmi les bibliothèques non-standard que
j'ai vu (surtout, mais non seulement, des gratuites), c'est
parmi le meiux documentée.

Ça ne veut pas dire que c'est bon, dans l'absolu, mais c'est au
moins un pas dans la bonne direction. (Je remarque en passant
que la qualité de la doc varie selon la bibliothèque, aussi.)

J'ai galéré quelques longues et interminables minutes pour
savoir quel header inclure pour mon adapteur d'itérateur...
Par contre, je sais tout sur les règles à respecter pour
soumettre un module à Boost. :-/


Tu n'as pas dû chercher au bon endroit:-).

Mais je crois aussi qu'une partie du problème, c'est qu'il offre
les classes et les fonctions avec un maximum de flexibilité. Ce
qui veut dire qu'il y a un maximum de choses à documenter, et
donc, beaucoup à étudier quand on ne veut que quelque chose tout
simple.

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


Avatar
Pierre THIERRY
Le Tue, 10 May 2005 00:29:24 -0700, kanze a écrit :
Par contre, [boost] est assez mal documentée vs-à-vis de
l'utilisateur final.
Par rapport à quoi ?



La STL, par exemple, dont je parcous la doc avec une relative aisance.

Tu n'as pas dû chercher au bon endroit:-).


Si. C'est simple, j'ai fait un grep de 'indirect_iterator.hpp' sur
l'ensemble de la doc de Boost, après coup, et cela n'apparaît que dans
des fichiers d'exemples. Qui incluent d'autres headers, qui sont
inutiles à l'utilisation de indirect_iterator.

La STL, en comparaison, mentionne pour chaque classe dans quels headers
elle est définie.

Et la doc de Boost est très orientée vers l'implémentation, et contient
beaucoup trop de code, et pas assez de texte. Mais je dois avouer
qu'elle est bien. Celle de la STL est mieux, mais les deux sont très
au-dessus de la plupart des bibli que j'ai vues (proprio ou libres, mais
je connais surtout le libre).

Documentairement,
Nowhere man
--

OpenPGP 0xD9D50D8A


Avatar
kanze
Pierre THIERRY wrote:
Par contre, [boost] est assez mal documentée vs-à-vis de
l'utilisateur final.
Par rapport à quoi ?



La STL, par exemple, dont je parcous la doc avec une relative
aisance.


Celle de la site SGI, n'est-ce pas ? C'est effectivement aussi
bien présenté.

Tu n'as pas dû chercher au bon endroit:-).


Si. C'est simple, j'ai fait un grep de 'indirect_iterator.hpp'
sur l'ensemble de la doc de Boost, après coup, et cela
n'apparaît que dans des fichiers d'exemples. Qui incluent
d'autres headers, qui sont inutiles à l'utilisation de
indirect_iterator.


C'est une façon un peu bizarre, non? Moi, je suis allé à
www.boost.org, j'ai cliqué sur le lien Documentation, et ensuite
sur le lien iterators. Là, c'est un peu plus compliqué, parce
qu'ils se sont rendus compte des faiblesses dans les itérateurs
à la STL, et qu'ils proposent des changements dans la norme pour
les corriger. Mais si je saute à la section, Specialized
Adaptors, je trouve un lien vers indirect_iterator, où je trouve
une documentation exemplaire.

La STL, en comparaison, mentionne pour chaque classe dans
quels headers elle est définie.


Ça, en revanche, est une bonne remarque. Il doivent bien mettre
cette information assez en avant sur la page indirect_iterator,
comme il se fait sur les pages man d'Unix. Ça manque.

Et la doc de Boost est très orientée vers l'implémentation, et
contient beaucoup trop de code, et pas assez de texte.


Sur la page de indirect_iterator, plus de la moitié du code sont
des exemples.

Mais je dois avouer qu'elle est bien. Celle de la STL est
mieux, mais les deux sont très au-dessus de la plupart des
bibli que j'ai vues (proprio ou libres, mais je connais
surtout le libre).


Celle de la STL sont en fait une référence. Tout ce que je peux
dire, c'est que et celle de la STL, et celle de Boost sont
nettement au dessus de ce que je vois d'habitude pour d'autres
bibliothèques.

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



Avatar
Loïc Joly
Pierre THIERRY wrote:

Je devrais survoler toute la doc de Boost pour savoir un peu
ce qu'il y dedans. Par contre, cette bibliothèque est assez
mal documentée vs-à-vis de l'utilisateur final.



Par rapport à quoi ? Parmi les bibliothèques non-standard que
j'ai vu (surtout, mais non seulement, des gratuites), c'est
parmi le meiux documentée.

Ça ne veut pas dire que c'est bon, dans l'absolu, mais c'est au
moins un pas dans la bonne direction. (Je remarque en passant
que la qualité de la doc varie selon la bibliothèque, aussi.)



Je rejoins l'avis de Pierre dans le sens où je n'ai rien à redire à
cette documentation en tant que référence, alors que pour
l'apprentissage, elle me semble souvent un peu faible, d'autant plus que
boost utilise des aspects du langage qui sont eux même parfois assez peu
maîtrisés.

Je ne peux pas comparer à d'autre bibliothèques libres, mais je sais
qu'aujourd'ui dans mon groupe de travail, c'est le principal frein à
l'utilisation de boost (et à aucune autre des bibliothèques que l'on
uilise), même si une fois le pas fait, mes collègues ont tendance à en
être contents.

Bon, je sais, si je suis pas content, je n'ai qu'à proposer mieux...
Mais je sais aussi que si un bon livre d'introduction à boost existait,
je serais tenté de l'acheter.

--
Loïc


Avatar
Pierre THIERRY
Le Tue, 10 May 2005 03:09:09 -0700, kanze a écrit :
[...] je trouve un lien vers indirect_iterator, où je trouve une
documentation exemplaire.


Pas exemplaire : on ne dit pas comment simplement se servir de la
classe. Et sans le fichier d'en-tête, c'est parfaitement impossible.

Sur la page de indirect_iterator, plus de la moitié du code sont des
exemples.


Des exemples qui ne sont pas compilables, puisque sans les directives
#include.

Brièvement,
Nowhere man
--

OpenPGP 0xD9D50D8A