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

Langage C++ Discussion :

Problème de specialization de methode template


Sujet :

Langage C++

  1. #1
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut Problème de specialization de methode template
    Bonjour!

    Je ne suis pas très familier avec la syntaxe de spécialisation des methodes d'une classe template. Je pense que mon problème n'est qu'un problème de syntaxe mais je ne trouve pas la solution.

    J'ai le code suivant :

    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
    /** Base class for curve representation.
            */
    	template< class PosType , unsigned short POS_TYPE_DIMENSION , class ValueType = float, class RelationType = float >
    	class Curve
    	{
    	public:
     
    		static const unsigned short DIMENSIONS = POS_TYPE_DIMENSION; 
     
    		/** Constructor.
                            @param beginPoint Point where the curve begins in it's origin period. (Pos 1.0f)
                            @param endPoint Point where the curve ends in it's origin period. (Pos 0.0f)
                    */
    		Curve( const PosType& beginPoint, const PosType& endPoint )
    			: m_beginPoint( beginPoint )
    			, m_endPoint( endPoint )
    		{;}
     
    		/** Destructor.
                    */
    		virtual ~Curve(){;}
     
    		/** Calculate the position of a point on the curve.
                            This method will call calculateFromEquation to determine the position of the point in the origin period.
                            @param curveRelativePos Define where on the curve the point is, 0 being the begin point and 1 the end point.
                            If this value is over 1 or under 0, the curve will be managed as a infinitely repeating sequence, like if 
                            between 0 and 1 it's a full period.
                    */
    		PosType calculatePoint( const RelationType& curveRelativePos );
     
    		/** Get the begin point of the curve (in it's origin period).
                    */
    		const PosType& getBeginPoint() const { return m_beginPoint; }
     
     
    		/** Get the end point of the curve (in it's origin period).
                    */
    		const PosType& getEndPoint() const { return m_endPoint; }
     
     
    	protected:
     
    		/// Begin point of the curve (in it's origin period).
    		const PosType& m_beginPoint;
     
    		/// End point of the curve (in it's origin period).
    		const PosType& m_endPoint;
     
    		/** Equation from witch we get the position of a point on the origin period of the curve.
                            @param posParamIdx Index of the member of the position type to use in the equation.
                            @param absRelationA Value between 0 and 1 that determine where is the value between the begin point and the end point.
                            @param absRelationB Value equal to : 1 - absRelationA
                    */
    		virtual ValueType calculateFromEquation( unsigned int posParamIdx, const RelationType& absRelationA , const RelationType& absRelationB ) = 0;
    	};
     
    	template< class PosType , unsigned short POS_TYPE_DIMENSION , class ValueType , class RelationType >
    	PosType Curve< PosType, POS_TYPE_DIMENSION, ValueType, RelationType >::calculatePoint( const RelationType& curveRelativePos )
    	{
    		const RelationType positiveCurveRelativePos = fabs( curveRelativePos );
    		const RelationType a = (positiveCurveRelativePos > 0 && positiveCurveRelativePos == ceil(positiveCurveRelativePos)) ? 1 : fmod( positiveCurveRelativePos , RelationType(1) );
    		const RelationType b = RelationType(1) - a;
     
    		const RelationType fullPeriodCount = (curveRelativePos == 0 ) ? 0 : (floor(curveRelativePos) - (floor(a) + floor(b))) ; // number of times we got OVER 1.0
    		const PosType lineVector = m_endPoint - m_beginPoint;
     
    		PosType resultPos;
     
    		if( fullPeriodCount >= 0 )
    		{
    			for( int i = 0; i < POS_TYPE_DIMENSION; ++i )
    			{
    				// note : the last part of the calculus is to allow having points farther than the begin point or the end point
    				resultPos[i] = this->calculateFromEquation( i, b, a) + ( fullPeriodCount * lineVector[i] ) ; 
    			}
    		}
    		else
    		{
    			for( int i = 0; i < POS_TYPE_DIMENSION; ++i )
    			{
    				// note : the last part of the calculus is to allow having points farther than the begin point or the end point
    				resultPos[i] = this->calculateFromEquation( i, a, b) + ( fullPeriodCount * lineVector[i] ) ; 
    			}
    		}
     
    		return resultPos;
    	}
     
    	// 1D specific version, assuming that PosType is not an array-like type
    	template< class PosType, class ValueType , class RelationType >
    	PosType Curve< PosType, 1, ValueType, RelationType >::calculatePoint< PosType, 1 , ValueType , RelationType >( const RelationType& curveRelativePos )
    	{
    		const RelationType positiveCurveRelativePos = fabs( curveRelativePos );
    		const RelationType a = (positiveCurveRelativePos > 0 && positiveCurveRelativePos == ceil(positiveCurveRelativePos)) ? 1 : fmod( positiveCurveRelativePos , RelationType(1) );
    		const RelationType b = RelationType(1) - a;
     
    		const RelationType fullPeriodCount = (curveRelativePos == 0 ) ? 0 : (floor(curveRelativePos) - (floor(a) + floor(b))) ; // number of times we got OVER 1.0
    		const PosType lineVector = m_endPoint - m_beginPoint;
     
    		PosType resultPos;
     
    		if( fullPeriodCount >= 0 )
    		{
    			// note : the last part of the calculus is to allow having points farther than the begin point or the end point
    			resultPos = this->calculateFromEquation( 0, b, a) + ( fullPeriodCount * lineVector ) ; 
     
    		}
    		else
    		{
    			// note : the last part of the calculus is to allow having points farther than the begin point or the end point
    			resultPos = this->calculateFromEquation( 0, a, b) + ( fullPeriodCount * lineVector ) ; 
     
    		}
     
    		return resultPos;
    	}

    Lorsque POS_TYPE_DIMENSION > 1 , j'ai bien ce que je veux, c'est à dire que c'est la première définition de calculatePoint qui est instanciée.

    En revanche, si j'ai POS_TYPE_DIMENSION == 1, (avec des types qui ne sont pas array-like) , j'obtiens une erreur parceque le compilateur essaie d'utiliser la première définition au lieu de la seconde. Du coup l'erreur point le fait que j'utilise [] sur un type qui n'est pas une array ni un pointeur ou autre.

    Mon but est simplement d'avoir le même algo sur une dimension qui partirait donc du principe que le type utilisé n'a pas d'operateur[]. J'ai juste besoin de spécialiser la seconde définition de calculatePoint pour le cas ou POS_TYPE_DIMENSION == 1 mais apparamment ce n'est pas la bonne syntaxe.


    Quelqu'un a une idée?

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    J'ajoute la classe héritée que j'utilise pour tester le code précédent.
    J'ai exactement le même problème là aussi :

    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
    	/** Line representation.
            */
    	template < class PosType , unsigned short POS_TYPE_DIMENSION , class ValueType = float, class RelationType = float >
    	class Line : public Curve< PosType, POS_TYPE_DIMENSION , ValueType , RelationType >
    	{
    	public:
     
    		/** Constructor.
                            @see Curve
                    */
    		Line( const PosType& beginPoint, const PosType& endPoint ) : Curve( beginPoint, endPoint ){}
    		~Line(){}
     
    	private:
     
    		/** Line equation.
                    */
    		ValueType calculateFromEquation( unsigned int posParamIdx, const RelationType& absRelationA , const RelationType& absRelationB );
     
    	};
     
     
    	template < class PosType , unsigned short POS_TYPE_DIMENSION , class ValueType , class RelationType >
    	ValueType Line< PosType, POS_TYPE_DIMENSION , ValueType , RelationType >::calculateFromEquation
    		( unsigned int posParamIdx, const RelationType& absRelationA , const RelationType& absRelationB )
    	{
    		return ( m_beginPoint[ posParamIdx ] * absRelationA ) + ( m_endPoint[ posParamIdx ] * absRelationB ) ;
    	}
     
    	// 1D specific version, assuming that PosType is not an array-like type
    	template < class PosType , class ValueType , class RelationType >
    	ValueType Line< PosType, 1 , ValueType , RelationType >::calculateFromEquation< PosType, 1, ValueType, RelationType >
    		( unsigned int posParamIdx, const RelationType& absRelationA , const RelationType& absRelationB )
    	{
    		GC_ASSERT( posParamIdx == 0, "Invalid index in 1D Line! Must be 0!" );
    		return ( m_beginPoint * absRelationA ) + ( m_endPoint * absRelationB ) ;
    	}

    Et le code pour tester, au cas ou vous voudriez tenter de compiler chez vous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    float posFloatA = 0.0f;
    		float posFloatB = 2.0f;
    		gcore::Line< float , 1 > test1DCurve( posFloatA, posFloatB );
     
    		float testFloatU = test1DCurve.calculatePoint( 0.0f );
    		float testFloatV = test1DCurve.calculatePoint( 0.5f );
    		float testFloatW = test1DCurve.calculatePoint( 1.0f );
    Normalement, testFloatU == 0.0f , testFloatV == 1.0f et testFloatW == 2.0f .

  3. #3
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    J'ai cherché encore tout a l'heure mais je ne trouve pas la subtilité pour que le compilo prenne la bonne version.

    Pas de spécialiste template dans le coin?

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut
    Salut,

    Si j'ai bien compris tu cherches à spécialiser partiellement une fonction membre de ta classe. Je crois malheureusement que ce n'est pas possible. Tu peux seulement spécialiser partiellement une classe template.

  5. #5
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Ou spécialiser totalement une fonction membre template

    Mais imaginons que tu ais N catégories de types pour ta fonction membre template, et ainsi N spécialisations partielles à faire (ce qui est impossible).

    Tu peux feinter en utilisant une classe de traits (http://alp.developpez.com/tutoriels/traitspolicies/ pour une bonne introduction aux classes de traits).

    Tu vas ainsi spécialiser autant de fois que tu veux ta classe de traits, de sortes que dans ta classe de traits tu ais un int (type_value) constant et statique, propre à chacune des N catégories.
    Je pense qu'en continuant sur cette piste tu peux t'en sortir.

  6. #6
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Merci je ne connaissais pas cette limitation dans les templates...

    Pour la classe de traits, j'aimerai garder mon système le plus simple possible, donc je vais déjà voir si ya pas un moyen simple de feinter la syntaxe array dans l'algorithme... Peut être avec un pointeur.
    Si je n'y arrive pas je vais voir pour le traits, merci de la suggestion

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

Discussions similaires

  1. Problème de map avec paramètre template
    Par bouba dans le forum Langage
    Réponses: 5
    Dernier message: 11/05/2007, 13h19
  2. [Joomla!] Problème de modification d'un template Joomla
    Par finalfx dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 08/03/2007, 15h52
  3. Problème avec une generic method
    Par Pragmateek dans le forum Langage
    Réponses: 15
    Dernier message: 24/05/2006, 19h25
  4. [phpBB] Function avec le Template phpBB
    Par mangafan dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 27/09/2005, 16h32
  5. [Template] methode template d'une classe pas template
    Par bigquick dans le forum Langage
    Réponses: 8
    Dernier message: 25/03/2005, 15h09

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