OVH Cloud OVH Cloud

Un vecteur dans une structure???

22 réponses
Avatar
Ataya
Voila, tout est dans le titre, je cherche a mettre un vecteur dans une
structure:

Voila mon code:

typedef struct {int xV;
int yV;
vector<tabVoisine>(1); }Ville;



Le message d'erreur:
Impossible de cr=E9er la sp=E9cialisation template depuis
'vector<T,Allocator>'


Je ne comprend pas le message d'erreur, qq'un aurait il une id=E9e,

Merci.

2 réponses

1 2 3
Avatar
Sylvain
Marc Boyer wrote on 27/03/2006 09:51:

Sauf que ce code déclare une variable Ville de type anonyme.
Je pense qu'il manque un typedef pour faire ce que vous vouliez
faire.


j'avais en effet plus un typedef en tête.
comme présentée ma remarque n'avait pas de sens, à oublier!

Sylvain.

Avatar
kanze
Jean-Marc Desperrier wrote:
kanze wrote:
Jean-Marc Desperrier wrote:
J'ai l'impression que cela peut cependant donner lieu à un bon
exemple d'utilisation des boost::weak_ptr.


Pas du tout. Il faut plus que simplement mettre à null un
pointeur.


J'ai l'impression que l'outils peut être utile, même si ce
n'est assurément pas la solution complète.


Peut-être dans certains cas, mais c'est loin d'être évident.
Comme j'ai dit, j'ai une classe à peu près équivalent, depuis au
moins six ou sept ans. Quand je l'ai développé, je croyais aussi
qu'il me serait plus généralement utile, mais dans les faits, ce
n'a pas été le cas. Il y a toujours eu quelque chose de plus à
faire, ce qui supposait une notification. Et une fois le
mechanisme de notification en place, il n'y avait plus tellement
d'intérêt dans le weak pointer.

La liste globales des villes serait gérée par des
boost::shared_ptr, les relations de voisinages par des
boost::weak_ptr, une suppression impromptue se régle
simplement en n'oubliant pas de tester l'échec de lock()
sur les weak_ptr.


Ce qui pose deux problèmes : d'abord, on a introduit une
collection globale qui n'y était pas avant, qu'il faut
gerer, et deuxièmement, on a une jolie fuite de mémoire, au
moins qu'on puisse garantir venir régarder les villes qui
n'y sont plus dans chacun des voisin d'avant.


Je me demande si on ne se comprend pas mal.
J'avais en tête de partir de ce qu'a proposé Etienne :

struct Ville
{
int xV;
int yV;
std::vector <Ville *> voisines;
// Cette structure ne fera que
// des affectation de pointeurs
};

struct Application
{
std::vector <Ville *> Villes;
// C'est cette structure qui fera les "new"
};

qui se transforme en :

class Ville
{
private:
std::vector< boost::weak_ptr<Ville> > voisines;
public:
int xV;
int yV;
std::vector< boost::shared_ptr<Ville> > getVoisines();
// getVoisines "lock" les voisines dans le vecteur retouné
// Au passage, elle nettoye la liste, et en retire les
// éléments expiré


C'est un peu lourd, non. Une copie profonde d'un std::vector (ou
plusieurs, si le compilateur n'implémente pas NRVO ou RVO). Même
en simplifiant :

boost::shared_ptr< Ville > getVoisine( size_t i ) ;

on impose un parcour complet du tableau à chaque accès. Pour
détecter un évenement qui est probablement très rare.

};

struct Application
{
std::vector< boost::shared_ptr<Ville> > Villes;
};


Et on introduit un objet de plus, avec le seul but de gérer...
mais au fond, de gérer quoi, en fait ? Et comment se prend-on
pour supprimer une ville ? L'utilisation de delete n'est
certainement pas indiqué.

En fait, il y a deux problèmes à résoudre : il faut s'assurer
que le rapport de voisinage soit commutatif, c-à-d que si a est
voisin de b, b est voisin d'a, et il faut s'assurer que dans le
cas où une ville est supprimée, que tous les rapports de
voisinage soient supprimés aussi.

A prioir, le premier impose déjà une gestion supplémentaire --
peut-être au moyen d'une notification. Utiliser la même gestion,
ou quelque chose de semblable, dans le cas de suppression d'une
ville me semble la solution la plus naturelle. On pourrait même
envisager le cas où la ville se déplace -- qu'elle était
voisine, mais qu'elle ne l'est plus. Probablement pas très utile
dans le rapport de voisinage entre villes, mais dans d'autres
rapports, si.

Je n'ai pas attendu Boost pour avoir quelque chose
d'équivalent, mais je m'en suis servi en fait assez peu,
parce que simplement mettre à null un pointeur, c'est rare
que ça suffisait.


Tout seul, certainement, mais il me semble qu'on peut
l'utiliser comme brique de base pour construire dessus ce qui
marche.


C'est qu'une fois qu'on a en place les notifications, il
apporte bien peu. Et qu'en général, il faut les notifications.
(Dans le cas de boost::weak_ptr, en plus, il impose
boost::shared_ptr, ce qui à sa tour impose une certaine
politique en ce qui concerne la durée de vie des objets.
Politique qui d'après mes expériences est rarement celle qu'on
veut -- depuis que j'utilise le collecteur de Boehm, je crois
que je n'ai pas utiliser des pointeurs à comptage de références
une seule fois.)

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