IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Conversion impossible objet classe fille en classe mere


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut Conversion impossible objet classe fille en classe mere
    Bonjour,
    Je dispose d'une fonction qui prend comme paramètre un objet de classe mere, lorsque j'essaye d'appeler cette fonction avec comme parametre un objet de classe fille le compilateur me jette, je ne comprend pas pourquoi, un objet de classe filles est bien considérer comme un objet de la classe mère "particulier" pourtant

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 25
    Points : 146
    Points
    146
    Par défaut
    En effet. A priori, pas de raison que ta classe fille soit refusée.

    Le problème vient peut être d'une erreur de syntaxe, d'une erreur dans la déclaration de la classe fille, d'un fichier include manquant qui ne permet pas au compilateur de savoir que cette classe fille hérite de la classe mère susnommée, etc ...

    Peut être qu'avec un extrait du code, une hypothèse se confirmera. Le message d'erreur exact pourrait être utile également.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    impossible de convertir le paramètre 3 de 'std::vector<_Ty>' en 'std::vector<_Ty> &'
    1> with
    1> [
    1> _Ty=Point3D_X_highter
    1> ]
    1> and
    1> [
    1> _Ty=Point3D
    1> ]
    1> main.cpp(36) : voir la référence à l'instanciation de la fonction modèle 'int execution<Point3D_X_highter>(std::map<_Kty,_Ty> &,std::vector<Point3D_X_highter> &,std::vector<Triangle> &,unsigned int)' en cours de compilation
    1> with
    1> [
    1> _Kty=Point3D_X_highter,
    1> _Ty=int
    1> ]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    #ifndef GEO
    #define GEO
     
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <stdint.h>
     
    //[comment]
    // Implementation of a generic vector class - it will be used to deal with 3D points, vectors and normals.
    // The class is implemented as a template. While it may complicate the code a bit, it gives us
    // the flexibility later, to specialize the type of the coordinates into anything we want.
    // For example: Vec3f if we want the coordinates to be floats or Vec3i if we want the coordinates to be integers.
    //
    // Vec3 is a standard/common way of naming vectors, points, etc. The OpenEXR and Autodesk libraries
    // use this convention for instance.
    //[/comment]
    template<typename T>
    class Vec3
    {
    public:
    	Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
    	Vec3(T xx) : x(xx), y(xx), z(xx) {}
    	Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
    	Vec3 operator + (const Vec3 &v) const
    	{ return Vec3(x + v.x, y + v.y, z + v.z); }
    	Vec3 operator - (const Vec3 &v) const
    	{ return Vec3(x - v.x, y - v.y, z - v.z); }
    	Vec3 operator - () const
    	{ return Vec3(-x, -y, -z); }
    	Vec3 operator * (const T &r) const
    	{ return Vec3(x * r, y * r, z * r); }
    	Vec3 operator * (const Vec3 &v) const
    	{ return Vec3(x * v.x, y * v.y, z * v.z); }
    	T dotProduct(const Vec3<T> &v) const
    	{ return x * v.x + y * v.y + z * v.z; }
    	Vec3& operator /= (const T &r)
    	{ x /= r, y /= r, z /= r; return *this; }
    	Vec3& operator *= (const T &r)
    	{ x *= r, y *= r, z *= r; return *this; }
    	Vec3 crossProduct(const Vec3<T> &v) const
    	{ return Vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); }
    	T norm() const
    	{ return x * x + y * y + z * z; }
    	T length() const
    	{ return sqrt(norm()); }
    // fonction non implémentée pour la classe mere du coup
    	/*bool operator < (const Vec3<T> &v) const
    	{
    	if (x != v.x)
    	return (x < v.x);
    	if (y != v.y)
    	return (y < v.y);
    	return (z < v.z);
    	}*/
     
    	//[comment]
    	// The next two operators are sometimes called access operators or
    	// accessors. The Vec coordinates can be accessed that way v[0], v[1], v[2],
    	// rather than using the more traditional form v.x, v.y, v.z. This useful
    	// when vectors are used in loops: the coordinates can be accessed with the
    	// loop index (e.g. v[i]).
    	//[/comment]
    	const T& operator [] (uint8_t i) const { return (&x)[i]; }
    	T& operator [] (uint8_t i) { return (&x)[i]; }
    	Vec3& normalize()
    	{
    		T n = norm();
    		if (n > 0) {
    			T factor = 1 / sqrt(n);
    			x *= factor, y *= factor, z *= factor;
    		}
    		return *this;
    	}
     
    	friend Vec3 operator * (const T &r, const Vec3 &v)
    	{ return Vec3<T>(v.x * r, v.y * r, v.z * r); }
    	friend Vec3 operator / (const T &r, const Vec3 &v)
    	{ return Vec3<T>(r / v.x, r / v.y, r / v.z); }
     
    	friend std::ostream& operator << (std::ostream &s, const Vec3<T> &v)
    	{
    		return s << '[' << v.x << ' ' << v.y << ' ' << v.z << ']';
    	}
     
     
    	T x, y, z;
    };
    template<typename T>
    T max3Values(T const& a, T const& b, T const& c){
    	return std::max(a,std::max(b,c));
    }
    template<typename T>
    T min3Values(T const& a, T const& b, T const& c){
    	return std::min(a,std::min(b,c));
    }
    //[comment]
    // Now you can specialize the class. We are just showing two examples here. In your code
    // you can declare a vector either that way: Vec3<float> a, or that way: Vec3f a
    //[/comment]
    typedef Vec3<float> Vec3f;
    typedef Vec3<float> Point3D;
    typedef Vec3<float> Normal;
    typedef Vec3<int> Vec3i;
    typedef Vec3<int> indPointsTriangle;
     
     
    class Point3D_X_highter : public Point3D
    {
    	template<typename T>
    	bool operator < (const Vec3<T> &v) const
    	{
    		if (x != v.x)
    			return (x < v.x);
    		if (y != v.y)
    			return (y < v.y);
    		return (z < v.z);
    	}
    };
     
     
    class Point3D_Y_highter: public Point3D
    {
    	template<typename T>
    	bool operator < (const Vec3<T> &v) const
    	{
    		if (y != v.y)
    			return (y < v.y);
    		if (x != v.x)
    			return (x < v.x);
    		return (z < v.z);
    	}
    };
     
    class Point3D_Z_highter: public Point3D
    {
    	template<typename T>
    	bool operator < (const Vec3<T> &v) const
    	{
    		if (z != v.z)
    			return (z < v.z);
    		if (x != v.x)
    			return (x < v.x);
    		return (y < v.y);
    	}
    };
    #endif

  4. #4
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Un std::vector<B> n’hérite jamais d’un std::vector<A>, même si B hérite de A.

    Sauf si j’ai lu trop vite, c’est ça ton problème (et donc parfaitement normal que ça ne compile pas).

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    Un compilateur qui me dit "impossible de convertir 'truc' en 'truc &'", pour moi, c'est surtout une tentative de prendre une temporaire en référence modifiante.
    Il n'y a que deux solutions: prendre par copie (ou faire une copie avant de prendre la référence), et prendre en référence constante.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Il semble que les deux erreurs ont été commises en même temps.
    Find me on github

  7. #7
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    après rectification sur conseil de leternel, l'erreur devient
    impossible de convertir le paramètre 2 de 'std::map<_Kty,_Ty>' en 'std::map<_Kty,_Ty>'
    1> with
    1> [
    1> _Kty=Point3D_X_highter,
    1> _Ty=int
    1> ]
    1> and
    1> [
    1> _Kty=Point3D,
    1> _Ty=int
    1> ]
    1> Aucun opérateur de conversion définie par l'utilisateur disponible qui puisse effectuer cette conversion, ou l'opérateur ne peut pas être appelé
    Donc en effet un vector<A> ou map<A> ne peut pas hérité d'un vector<B> ou une map<B>

  8. #8
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    Pour vous détailler l'idée, je souhaite pouvoir utilisé soit :
    - un point3D où x est considéré le plus fort pour la comparaison, nommé Point3D_X_highter héritié de Point3D
    - un point3D où y est considéré le plus fort pour la comparaison, nommé Point3D_Y_highter héritié de Point3D
    - un point3D où z est considéré le plus fort pour la comparaison, nommé Point3D_Z_highter héritié de Point3D

    Ainsi ma map sera triée de manière différente selon qu'elle a pour clef un Point3D_X_highter ou Point3D_Y_highter ou Point3D_Z_highter

  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    Essaie plutot d'utiliser des comparateurs différents (troisieme argument template de map), et une seule définition de point.

    Ca ne résoudra pas forcément ton problème immédiat, mais tu auras séparé la donnée de son tri.
    Quant au détail, en anglais, l'adjectif est high, et le comparatif higher.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,
    Citation Envoyé par romainprogdebutant Voir le message
    Pour vous détailler l'idée, je souhaite pouvoir utilisé soit :
    - un point3D où x est considéré le plus fort pour la comparaison, nommé Point3D_X_highter héritié de Point3D
    - un point3D où y est considéré le plus fort pour la comparaison, nommé Point3D_Y_highter héritié de Point3D
    - un point3D où z est considéré le plus fort pour la comparaison, nommé Point3D_Z_highter héritié de Point3D

    Ainsi ma map sera triée de manière différente selon qu'elle a pour clef un Point3D_X_highter ou Point3D_Y_highter ou Point3D_Z_highter
    Cela représente à vrai dire un énorme problème de conception

    En effet, tu peux très bien trouver, à un instant T, plusieurs instances de ta classe point qui de valeurs strictement identiques (ex 3 en X, 4 en Y et 5 en Z). Du coup, ta classe point, quelle que soit la forme qu'elle prend, a ce que l'on appelle une sémantique de valeur.

    Or, ainsi que le lien l'indique, une classe ayant sémantique de valeur ne peut pas servir dans une relation d'héritage. Ce sont les classes dont on dit qu'elles ont sémantique d'entité qui ont ce pouvoir

    Ceci étant dit, il faut savoir que l'on utilise généralement deux paramètres template lorsque l'on manipule std::map : le premier qui représente la clé et le deuxième qui représente la valeur. Mais il est aussi possible d'utiliser un troisième paramètre template qui correspond au prédicat à utiliser pour le tri des clés.

    Ainsi, tu pourrais créer trois foncteurs, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    struct LessByX{
        bool operator()(Point3D const & p1, Point3D const & p2) const{
            return p1.x() < p2.x();
        }
    }
    struct LessByY{
        bool operator()(Point3D const & p1, Point3D const & p2) const{
            return p1.y() < p2.y();
        }
    }
    struct LessByZ{
        bool operator()(Point3D const & p1, Point3D const & p2) const{
            return p1.z() < p2.z();
        }
    }
    que tu pourrais utiliser (selon tes besoins) sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::map<Point3D, /* valeur */, LessByX> tri_par_X;
    std::map<Point3D, /* valeur */, LessByY> tri_par_Y;
    std::map<Point3D, /* valeur */, LessByZ> tri_par_Z;
    MAIS... tu ne pourras (me semble-t-il du moins) pas la transmettre à une fonction dont le prototype serait simplement proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void foo(std::map<Point3D, /*valeur */> const & param);
    Tu devras, pour chaque fonction appelée, soit spécifier explicitement le foncteur de tri sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void foo(std::map<Point3D, /*valeur */, LessByX> const & param);
    A moins bien sur de créer une fonction template qui puisse ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename Pred>
    void bar(std::map<Point3D, /* valeur */, Pred> const & param);
    <EDIT>Note : aucune des collections de la SL n'est prévue pour pouvoir servir de classe de base... cela se remarque facilement : leur destructeur n'est jamais virtuel et, qui plus est, elles autorisent la construction de copie et l'affectation </EDIT>
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    Merci ! beaucoup ! J'ai mieux compris l'idéee. Je crois que je touche le bout, j'ai fait comme leternel et koala01 m'ont dit mais je tombe sur une violente erreur ou du moins bien longue

    >main.obj : error LNK2019: symbole externe non résolu "int __cdecl loadStlAsciiFile<class CompareX>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::map<class Vec3<float>,int,class CompareX,class std::allocator<struct std::pair<class Vec3<float> const ,int> > > &,class std::vector<class Vec3<float>,class std::allocator<class Vec3<float> > > &,class std::vector<class Triangle,class std::allocator<class Triangle> > &)" (??$loadStlAsciiFile@VCompareX@@@@YAHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV?$map@V?$Vec3@M@@HVCompareX@@V?$allocator@U?$pair@$$CBV?$Vec3@M@@H@std@@@std@@@1@AAV?$vector@V?$Vec3@M@@V?$allocator@V?$Vec3@M@@@std@@@1@AAV?$vector@VTriangle@@V?$allocator@VTriangle@@@std@@@1@@Z) référencé dans la fonction _main

    1> fatal error LNK1120: 1 externes non résolus

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Ca, c'est une erreur d'éditions de liens : l'éditeur de liens se plaint de n'avoir pas trouvé le code binaire d'une fonction pour laquelle il a croisé un appel.

    Dés lors,
    1. n'aurais tu pas, dans ta fonction main, un appel à une fonction nommée "loadStlAsciFile"
    2. Si oui, l'as tu correctement implémentée :question
    3. Ne serait-ce pas une fonction template dont la définition se trouve dans un fichier portant l'extension *.cpp
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    1.n'aurais tu pas, dans ta fonction main, un appel à une fonction nommée "loadStlAsciFile"
    vi
    2.Si oui, l'as tu correctement implémentée :question
    Comme j'utilise les templates j'ai mis en entête ça dans la .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename T>
    int loadStlAsciiFile(string const&fileName, map<Point3D,int,T> &orderedPointsList, vector<Point3D> &pointsList, vector<Triangle> &triangles){...
    et ça dans le .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename T>
    int loadStlAsciiFile(std::string const&fileName, std::map<Point3D,int,T> &orderedPointsList, std::vector<Point3D> &pointsList, std::vector<Triangle> &triangles);
    3.Ne serait-ce pas une fonction template dont la définition se trouve dans un fichier portant l'extension *.cpp
    oui

  14. #14
    Membre à l'essai
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Juin 2015
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Juin 2015
    Messages : 31
    Points : 21
    Points
    21
    Par défaut
    du coup j'ai mis ma fonction template entière dans le .h, ça marche ! merci

  15. #15
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par koala01 Voir le message
    MAIS... tu ne pourras (me semble-t-il du moins) pas la transmettre à une fonction dont le prototype serait simplement proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void foo(std::map<Point3D, /*valeur */> const & param);
    C'est possible en encapsulant le comparateur dans un comparateur plus général :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    template <class T>
    struct less_by {
    	typedef std::function<bool(T const&, T const&)> fct_t;
     
    	less_by(fct_t const& f) : m_cmp(f)
    	{ }
     
    	bool operator()(T const& lhs, T const& rhs) const {
    		return m_cmp(lhs, rhs);
    	}
     
    private:
    	fct_t m_cmp;
    };
     
    template<class T>
    bool byX(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.x < rhs.x;
    }
     
    template<class T>
    bool byY(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.y < rhs.y;
    }
     
    template<class T>
    bool byZ(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.z < rhs.z;
    }
     
    typedef Vec<float> Vecf;
    typedef std::map<Vecf, int, less_by<Vecf>> map_t;
     
    map_t mapByX((less_by<Vecf>(byX<float>))); // pas de déduction de types ici :( (les parenthèses empêchent d'interpréter ça comme une déclaration de fonction et non de variable)
    map_t mapByY((less_by<Vecf>(byY<float>)));
    map_t mapByZ((less_by<Vecf>(byZ<float>)));
    Le type du comparateur est le même dans tous les cas ici.

    Code complet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    #include <iostream>
    #include <functional>
    #include <map>
     
    template <class T>
    struct Vec {
    	Vec() { }
    	Vec(T x, T y, T z) : x(x), y(y), z(z) { }
    	Vec(Vec const& other) : x(other.x), y(other.y), z(other.z) { }
    	Vec& operator=(Vec const& other) {
    		x = other.x;
    		y = other.y;
    		z = other.z;
    		return *this;
    	}
     
    	T x, y, z;
    };
     
    template <class T>
    std::ostream& operator<<(std::ostream& s, Vec<T> const& vec) {
    	s << vec.x << " " << vec.y << " " << vec.z;
    	return s;
    }
     
    template <class T>
    struct less_by {
    	typedef std::function<bool(T const&, T const&)> fct_t;
     
    	less_by(fct_t const& f) : m_cmp(f)
    	{ }
     
    	bool operator()(T const& lhs, T const& rhs) const {
    		return m_cmp(lhs, rhs);
    	}
     
    private:
    	fct_t m_cmp;
    };
     
     
    template<class T>
    bool byX(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.x < rhs.x;
    }
     
    template<class T>
    bool byY(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.y < rhs.y;
    }
     
    template<class T>
    bool byZ(Vec<T> const& lhs, Vec<T> const& rhs) {
    	return lhs.z < rhs.z;
    }
     
     
    typedef Vec<float> Vecf;
    typedef std::map<Vecf, int, less_by<Vecf>> map_t;
     
    void insert(map_t& m, Vecf const& key, int value) {
    	m.insert(std::make_pair(key, value));
    }
     
    void print(map_t const& m) {
    	for (auto const& pair : m) {
    		std::cout << pair.first << " -> " << pair.second << std::endl;
    	}
    }
     
    int main(int, char**) {
    	map_t mapByX((less_by<Vecf>(byX<float>)));
    	map_t mapByY((less_by<Vecf>(byY<float>)));
    	map_t mapByZ((less_by<Vecf>(byZ<float>)));
     
    	Vecf v0(0.f, 1.f, 2.f);
    	Vecf v1(1.f, 2.f, 0.f);
    	Vecf v2(2.f, 0.f, 1.f);
     
    	insert(mapByX, v0, 0);
    	insert(mapByX, v1, 1);
    	insert(mapByX, v2, 2);
     
    	insert(mapByY, v0, 0);
    	insert(mapByY, v1, 1);
    	insert(mapByY, v2, 2);
     
    	insert(mapByZ, v0, 0);
    	insert(mapByZ, v1, 1);
    	insert(mapByZ, v2, 2);
     
    	std::cout << "x\n";
    	print(mapByX);
     
    	std::cout << "y\n";
    	print(mapByY);
     
    	std::cout << "z\n";
    	print(mapByZ);
     
    	return 0;
    }
    Par contre, on passe par une pointeur de fonction, ça peut avoir un impact sur les perfs.

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Bien vu, Iradrille, j'avoue que je n'y avais pas pensé

    Voilà une fois de plus la preuve que tout problème peut être résolu en ajoutant un niveau d'indirection supplémentaire

    Il faut cependant être bien clair : bien que cela permette de ne pas **trop** chipoter au niveau des fonctions qui prendront la map en paramètre, il n'y a toujours aucun lien entre les différents types de map : les variables que tu as définies comme étant mapByX, mapByY et mapByZ restent des variables de type totalement différents (bien que suffisamment proches pour profiter du polymorphisme paramétrique et du polymorphisme et, d'une certaine manière, de la coercition )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #17
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par koala01 Voir le message
    il n'y a toujours aucun lien entre les différents types de map : les variables que tu as définies comme étant mapByX, mapByY et mapByZ restent des variables de type totalement différents
    Je ne sais pas trop de quel point de vue tu t’es placé, mais du point de vue du système de type C++, elles sont bel et bien du même type.

    C’est d’ailleurs un peu ce qui m’ennuie avec cette approche. On mélange des choux et des carottes (elles ont bien une sémantique différente).

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    En effet, j'ai dit une bêtise... la fonction utilisée est fournie sous la forme d'un paramètre, et non d'un paramètre template, ce qui fait que le type de la map ne dépend absolument pas de la comparaison effectuée

    La seule chose que l'on aie au final, c'est que chaque variable doit indiquer la comparaison, mais elles sont tout à fait interchangeables entre elles. Cela pose effectivement un problème moral à cause de la sémantique de chaque instance, mais cela peut aussi -- dans certaines circonstances -- nous éviter le recours à des techniques plus crades encore
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Caster classe mère et classe fille
    Par zsoufianz dans le forum Général Java
    Réponses: 1
    Dernier message: 02/12/2014, 04h36
  2. Conversion d'une classe mère en classe fille
    Par Aleph69 dans le forum C++
    Réponses: 7
    Dernier message: 07/05/2014, 11h39
  3. Appel méthode classe fille, dont classe mère virtuelle
    Par Metalman dans le forum Débuter
    Réponses: 6
    Dernier message: 07/06/2013, 12h51
  4. Réponses: 6
    Dernier message: 22/07/2010, 16h17
  5. caster une classe mère en classe fille
    Par franchouze dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 01/10/2009, 12h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo