C'est un peu confus.
pair<set<const Cluster*>::iterator,bool> p;
[...]
p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis
que le type de Influences -- ou un de ses types de base -- est
set<const Cluster*>. Il suit que le tri est fait avec std::less< const
Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
C'est un peu confus.
pair<set<const Cluster*>::iterator,bool> p;
[...]
p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis
que le type de Influences -- ou un de ses types de base -- est
set<const Cluster*>. Il suit que le tri est fait avec std::less< const
Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
C'est un peu confus.
pair<set<const Cluster*>::iterator,bool> p;
[...]
p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis
que le type de Influences -- ou un de ses types de base -- est
set<const Cluster*>. Il suit que le tri est fait avec std::less< const
Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
Franck Branjonneau avait énoncé :C'est un peu confus.
c'est pas simple a expliquer sans en dire des tonnes aussi...
désolé j'aurai du mettre la déclaration du set :
set<const Cluster *,CompareDistance> Influences;
avec le foncteur CompareDistance :
class CompareDistance
{
private:
const Cluster *p;
public:
CompareDistance(const Cluster &c);
bool operator()(const Cluster *c1, const Cluster *c2) const;
};
CompareDistance::CompareDistance(const Cluster &c)
:p(&c)
{
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
et tout ça, en fait je viens de me rendre compte que ça marche très
bien pour n cluster dans u vector simple...
Franck Branjonneau avait énoncé :
C'est un peu confus.
c'est pas simple a expliquer sans en dire des tonnes aussi...
désolé j'aurai du mettre la déclaration du set :
set<const Cluster *,CompareDistance> Influences;
avec le foncteur CompareDistance :
class CompareDistance
{
private:
const Cluster *p;
public:
CompareDistance(const Cluster &c);
bool operator()(const Cluster *c1, const Cluster *c2) const;
};
CompareDistance::CompareDistance(const Cluster &c)
:p(&c)
{
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
et tout ça, en fait je viens de me rendre compte que ça marche très
bien pour n cluster dans u vector simple...
Franck Branjonneau avait énoncé :C'est un peu confus.
c'est pas simple a expliquer sans en dire des tonnes aussi...
désolé j'aurai du mettre la déclaration du set :
set<const Cluster *,CompareDistance> Influences;
avec le foncteur CompareDistance :
class CompareDistance
{
private:
const Cluster *p;
public:
CompareDistance(const Cluster &c);
bool operator()(const Cluster *c1, const Cluster *c2) const;
};
CompareDistance::CompareDistance(const Cluster &c)
:p(&c)
{
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
et tout ça, en fait je viens de me rendre compte que ça marche très
bien pour n cluster dans u vector simple...
set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
Franck Branjonneau a formulé ce dimanche :set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
dans le constructeur de cluster :
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
{
Parent = NULL; //pas de parent lors de sa construction
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
Franck Branjonneau a formulé ce dimanche :
set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
dans le constructeur de cluster :
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
{
Parent = NULL; //pas de parent lors de sa construction
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
Franck Branjonneau a formulé ce dimanche :set<const Cluster *,CompareDistance> Influences;
C'est un membre du type Cluster ? Quand et comment est-il initialisé ?
dans le constructeur de cluster :
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
{
Parent = NULL; //pas de parent lors de sa construction
}
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
Nicolas Aunai icrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
Nicolas Aunai <nicolas.aunai@free.fr> icrivait:
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
Nicolas Aunai icrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
Nicolas Aunai icrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
Nicolas Aunai <nicolas.aunai@free.fr> icrivait:
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
Nicolas Aunai icrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
bool
CompareDistance::operator()(const Cluster *c1, const Cluster *c2) const
{
return c1->Distance(*p) < c2->Distance(*p);
}
Attention, les résultats qui suivent laissent à penser que
Cluster::Distance retourne un type réel que se passe-t-il si les
distances des clusters pointés par c1 et c2 au cluster pointé par p
sont proches ?
double Distance(const Cluster &c) const;
les distances par rapport a p qui est l'objet courant en fait, sont
comparées et ensuite insérées dans le set.
J'avais compris. L'objet de ma question est de te faire
remarquer que le type double à les limites de sa représentation.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
qui est un membre de 'Cluster' du type 'set<Cluster const*, CompareDistance>'
et qui détiendra une instance de 'CompareDistance' avec un pointeur 'this',
ne dépasse pas la durée de vie de l'objet 'Cluster' désigné par '*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de 'Cluster'
et ces instances n'ont pas forcement la même durée de vie que l'instance
désignée par '*this' (par exemple suite au rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le 'vector'
et gérer proprement la durée de vie des instances de 'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster' donnée
soient enlevés de tous les 'Influences' avant sa destruction
* La relation d'ordre servant à déterminer l'endroit d'insertion d'un
élément dans un 'set' ne doit pas changer "à la volée" sinon ça risque
de faire désordre... Es-tu sûr que les coordonnées de ton 'Cluster'
(apparemment le champ 'Position' comportant trois 'double' ?) ne
varient pas pendant la durée de vie de ton objet ? Le mieux est de
déclarer ce champ 'const' ce qui empêchera entre autres l'affectation
de 'Cluster' (et par conséquence l'instantiation de 'std::vector<Cluster>',
solution : voir ci-dessus)
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point donné
en "arithmétique flottante de la machine" (ce qui devrait être le cas, par
exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0, 0 ]), 'std::set'
ne gardera que le premier inséré. D'où mon conseil dans l'autre post de
regarder plutôt 'std::multiset'.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
qui est un membre de 'Cluster' du type 'set<Cluster const*, CompareDistance>'
et qui détiendra une instance de 'CompareDistance' avec un pointeur 'this',
ne dépasse pas la durée de vie de l'objet 'Cluster' désigné par '*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de 'Cluster'
et ces instances n'ont pas forcement la même durée de vie que l'instance
désignée par '*this' (par exemple suite au rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le 'vector'
et gérer proprement la durée de vie des instances de 'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster' donnée
soient enlevés de tous les 'Influences' avant sa destruction
* La relation d'ordre servant à déterminer l'endroit d'insertion d'un
élément dans un 'set' ne doit pas changer "à la volée" sinon ça risque
de faire désordre... Es-tu sûr que les coordonnées de ton 'Cluster'
(apparemment le champ 'Position' comportant trois 'double' ?) ne
varient pas pendant la durée de vie de ton objet ? Le mieux est de
déclarer ce champ 'const' ce qui empêchera entre autres l'affectation
de 'Cluster' (et par conséquence l'instantiation de 'std::vector<Cluster>',
solution : voir ci-dessus)
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point donné
en "arithmétique flottante de la machine" (ce qui devrait être le cas, par
exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0, 0 ]), 'std::set'
ne gardera que le premier inséré. D'où mon conseil dans l'autre post de
regarder plutôt 'std::multiset'.
À priori ça ne pose pas de problème car la durée de vie de 'Influences'
qui est un membre de 'Cluster' du type 'set<Cluster const*, CompareDistance>'
et qui détiendra une instance de 'CompareDistance' avec un pointeur 'this',
ne dépasse pas la durée de vie de l'objet 'Cluster' désigné par '*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de 'Cluster'
et ces instances n'ont pas forcement la même durée de vie que l'instance
désignée par '*this' (par exemple suite au rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le 'vector'
et gérer proprement la durée de vie des instances de 'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster' donnée
soient enlevés de tous les 'Influences' avant sa destruction
* La relation d'ordre servant à déterminer l'endroit d'insertion d'un
élément dans un 'set' ne doit pas changer "à la volée" sinon ça risque
de faire désordre... Es-tu sûr que les coordonnées de ton 'Cluster'
(apparemment le champ 'Position' comportant trois 'double' ?) ne
varient pas pendant la durée de vie de ton objet ? Le mieux est de
déclarer ce champ 'const' ce qui empêchera entre autres l'affectation
de 'Cluster' (et par conséquence l'instantiation de 'std::vector<Cluster>',
solution : voir ci-dessus)
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point donné
en "arithmétique flottante de la machine" (ce qui devrait être le cas, par
exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0, 0 ]), 'std::set'
ne gardera que le premier inséré. D'où mon conseil dans l'autre post de
regarder plutôt 'std::multiset'.
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point
donné en "arithmétique flottante de la machine" (ce qui devrait être
le cas, par exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0,
0 ]), 'std::set' ne gardera que le premier inséré. D'où mon conseil
dans l'autre post de regarder plutôt 'std::multiset'.
bon bref... là n'est pas le problème je pense puisque le tri marche
parfaitement si j'utilise uniquement ma classe cluster et un vector
simple au lieu de mon systeme.
En mettant
je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
c'est compilable et ça représente juste un vector de cluster... on
constate que le tri se fait bien...
maintenant, je remplace le vector de cluster par ma classe Systeme (qui
n'est pas super bien faite mais bon... doit y avoir une erreur sinon ça
marcherai)
et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
voila, tout ceci montre que l'erreur se trouve vraissemblablement dans
la classe systeme car son utilisation vient foutre ce comportement
bizarre qui 'était pas là avec le simple vector du test de cluster...
Le problème vient du fait que 'std::vector' a besoin du constructeur de
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point
donné en "arithmétique flottante de la machine" (ce qui devrait être
le cas, par exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0,
0 ]), 'std::set' ne gardera que le premier inséré. D'où mon conseil
dans l'autre post de regarder plutôt 'std::multiset'.
bon bref... là n'est pas le problème je pense puisque le tri marche
parfaitement si j'utilise uniquement ma classe cluster et un vector
simple au lieu de mon systeme.
En mettant
je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
c'est compilable et ça représente juste un vector de cluster... on
constate que le tri se fait bien...
maintenant, je remplace le vector de cluster par ma classe Systeme (qui
n'est pas super bien faite mais bon... doit y avoir une erreur sinon ça
marcherai)
et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
voila, tout ceci montre que l'erreur se trouve vraissemblablement dans
la classe systeme car son utilisation vient foutre ce comportement
bizarre qui 'était pas là avec le simple vector du test de cluster...
Le problème vient du fait que 'std::vector' a besoin du constructeur de
Effectivement. Par exemple, les points [ 8, 2, 4.1 ] et [ 1, 1, 9.1 ]
ont la même distance sqrt(84.81) au point [ 0, 0, 0 ] en arithmétique
exacte, mais avec mon compilateur (gcc 3.3.1 i686-pc-cygwin) j'obtiens
une différence de 7.71952e-16 entre les deux distances avec des 'double'.
Par contre, si deux points ont exactement la même distance à un point
donné en "arithmétique flottante de la machine" (ce qui devrait être
le cas, par exemple, pour [ 1, 2, 10 ] et[ -4, 5, 8 ] au point [ 0, 0,
0 ]), 'std::set' ne gardera que le premier inséré. D'où mon conseil
dans l'autre post de regarder plutôt 'std::multiset'.
bon bref... là n'est pas le problème je pense puisque le tri marche
parfaitement si j'utilise uniquement ma classe cluster et un vector
simple au lieu de mon systeme.
En mettant
je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
c'est compilable et ça représente juste un vector de cluster... on
constate que le tri se fait bien...
maintenant, je remplace le vector de cluster par ma classe Systeme (qui
n'est pas super bien faite mais bon... doit y avoir une erreur sinon ça
marcherai)
et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
voila, tout ceci montre que l'erreur se trouve vraissemblablement dans
la classe systeme car son utilisation vient foutre ce comportement
bizarre qui 'était pas là avec le simple vector du test de cluster...
Le problème vient du fait que 'std::vector' a besoin du constructeur de
Franck Branjonneau wrote:Nicolas Aunai écrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de
'Influences' qui est un membre de 'Cluster' du type 'set<Cluster
const*, CompareDistance>' et qui détiendra une instance de
'CompareDistance' avec un pointeur 'this', ne dépasse pas la durée
de vie de l'objet 'Cluster' désigné par'*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de
'Cluster' et ces instances n'ont pas forcement la même durée de vie
que l'instance désignée par '*this' (par exemple suite au
rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le
'vector' et gérer proprement la durée de vie des instances de
'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster'
donnée soient enlevés de tous les 'Influences' avant sa
destruction
Franck Branjonneau wrote:
Nicolas Aunai <nicolas.aunai@free.fr> écrivait:
Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de
'Influences' qui est un membre de 'Cluster' du type 'set<Cluster
const*, CompareDistance>' et qui détiendra une instance de
'CompareDistance' avec un pointeur 'this', ne dépasse pas la durée
de vie de l'objet 'Cluster' désigné par
'*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de
'Cluster' et ces instances n'ont pas forcement la même durée de vie
que l'instance désignée par '*this' (par exemple suite au
rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le
'vector' et gérer proprement la durée de vie des instances de
'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster'
donnée soient enlevés de tous les 'Influences' avant sa
destruction
Franck Branjonneau wrote:Nicolas Aunai écrivait:Cluster::Cluster(const double a,
const double b,
const double c,
const unsigned int gen)
:Position(a,b,c),Influences(CompareDistance(*this)),Fils(),Generation(gen)
Tes instances de CompareDistance sont initialisées avec un pointeur
this qui est invalidé quand ton système, ton std::vector de Cluster,
est redimensionné.
À priori ça ne pose pas de problème car la durée de vie de
'Influences' qui est un membre de 'Cluster' du type 'set<Cluster
const*, CompareDistance>' et qui détiendra une instance de
'CompareDistance' avec un pointeur 'this', ne dépasse pas la durée
de vie de l'objet 'Cluster' désigné par'*this'.
Deux choses qui peuvent poser problème :
* 'Influences' stocke des pointeurs sur d'autres instances de
'Cluster' et ces instances n'ont pas forcement la même durée de vie
que l'instance désignée par '*this' (par exemple suite au
rédimensionnement du 'vector').
Solution possible : Stocker des pointeurs sur 'Cluster' dans le
'vector' et gérer proprement la durée de vie des instances de
'Cluster' ;
être sûr que tous les pointeurs sur une instance de 'Cluster'
donnée soient enlevés de tous les 'Influences' avant sa
destruction
Nicolas Aunai wrote:je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
(qui n'est pas super bien faite mais bon... doit y avoir une erreur
sinon ça marcherai) et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
Le problème vient du fait que 'std::vector' a besoin du constructeur
de copie et de l?opérateur d?affectation, et ta classe 'Cluster'
utilise les opérations générées par le compilateur qui ne marchent
pas bien parce que le champ ?Influences? aura un functeur de
comparaison pointant sur le 'Cluster' d?origine plutôt que l?objet
courant. Par conséquent, les distances à l?insertion sont calculées
par rapport à ce premier...
En mettant
Cluster::Cluster(Cluster const& c)
: Position(c.Position),
Influences(c.Influences.begin(), c.Influences.end(), CompareDistance(*this)),
Parent(c.Parent),
Generation(c.Generation)
{
}
Cluster& Cluster::operator=(Cluster const& c)
{
Position = c.Position;
Influences.clear();
Influences.insert(c.Influences.begin(), c.Influences.end());
Parent = c.Parent;
Generation = c.Generation;
return *this;
}
cela se passe mieux.
Reste la question si la classe 'Cluster' doit réellement avoir une
sémantique de valeur ou s?il faut en interdire les opérations de
copie (ce qui obligerait entre autres de remplacer
'std::vector<Cluster>' par 'std::vector<Cluster*>').
Nicolas Aunai wrote:
je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
(qui n'est pas super bien faite mais bon... doit y avoir une erreur
sinon ça marcherai) et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
Le problème vient du fait que 'std::vector' a besoin du constructeur
de copie et de l?opérateur d?affectation, et ta classe 'Cluster'
utilise les opérations générées par le compilateur qui ne marchent
pas bien parce que le champ ?Influences? aura un functeur de
comparaison pointant sur le 'Cluster' d?origine plutôt que l?objet
courant. Par conséquent, les distances à l?insertion sont calculées
par rapport à ce premier...
En mettant
Cluster::Cluster(Cluster const& c)
: Position(c.Position),
Influences(c.Influences.begin(), c.Influences.end(), CompareDistance(*this)),
Parent(c.Parent),
Generation(c.Generation)
{
}
Cluster& Cluster::operator=(Cluster const& c)
{
Position = c.Position;
Influences.clear();
Influences.insert(c.Influences.begin(), c.Influences.end());
Parent = c.Parent;
Generation = c.Generation;
return *this;
}
cela se passe mieux.
Reste la question si la classe 'Cluster' doit réellement avoir une
sémantique de valeur ou s?il faut en interdire les opérations de
copie (ce qui obligerait entre autres de remplacer
'std::vector<Cluster>' par 'std::vector<Cluster*>').
Nicolas Aunai wrote:je mets une version du code qui marche ici :
http://nicolas.aunai.free.fr/particule/points/ok
(qui n'est pas super bien faite mais bon... doit y avoir une erreur
sinon ça marcherai) et le code est là :
http://nicolas.aunai.free.fr/particule/points/paok
Le problème vient du fait que 'std::vector' a besoin du constructeur
de copie et de l?opérateur d?affectation, et ta classe 'Cluster'
utilise les opérations générées par le compilateur qui ne marchent
pas bien parce que le champ ?Influences? aura un functeur de
comparaison pointant sur le 'Cluster' d?origine plutôt que l?objet
courant. Par conséquent, les distances à l?insertion sont calculées
par rapport à ce premier...
En mettant
Cluster::Cluster(Cluster const& c)
: Position(c.Position),
Influences(c.Influences.begin(), c.Influences.end(), CompareDistance(*this)),
Parent(c.Parent),
Generation(c.Generation)
{
}
Cluster& Cluster::operator=(Cluster const& c)
{
Position = c.Position;
Influences.clear();
Influences.insert(c.Influences.begin(), c.Influences.end());
Parent = c.Parent;
Generation = c.Generation;
return *this;
}
cela se passe mieux.
Reste la question si la classe 'Cluster' doit réellement avoir une
sémantique de valeur ou s?il faut en interdire les opérations de
copie (ce qui obligerait entre autres de remplacer
'std::vector<Cluster>' par 'std::vector<Cluster*>').