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 :

[Template] < T, T inValue1, T inValue2> Mingw : compilation erreur ( VC : ok )


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Suryavarman
    Homme Profil pro
    Développeur 3D
    Inscrit en
    Mai 2006
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur 3D
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2006
    Messages : 233
    Par défaut [Template] < T, T inValue1, T inValue2> Mingw : compilation erreur ( VC : ok )
    Bonjour à tous.

    J'ai une fonction définie comme ce qui suit :

    Header :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    namespace Ca
    {
        namespace Math
        {
            /** Retourne l'angle compris dans l'intervalle [inOrigine, inOrigine + inModulo]
            *   @remarks inModulo peut être négatif
            */
            template< typename T, T inOrigine, T inModulo >
            T GetRadianAngleModulo( T inRadianAngle ) ;
        }
    }
    #include "Ca/Math.tpp"
    Template corps :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template< typename T, T inOrigine, T inModulo >
    T Ca::Math::GetRadianAngleModulo( T inRadianAngle )
    {
        T aAlpha = std::atan2( std::sin( inRadianAngle ), std::cos( inRadianAngle ) ) ;
     
    	aAlpha += inModulo ;
     
        // http://pubs.opengroup.org/onlinepubs/007904975/functions/fmod.html
        T aY = inOrigine + inModulo ;
    	return aY ? std::fmod( aAlpha, inOrigine + inModulo ) + inOrigine : aAlpha + inOrigine ;
    }
    Elle est appelée de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    float aResult = Ca::Math::GetRadianAngleModulo<float, 0, 6.2831853071795f>( m_SurfaceNode->getOrientation().getYaw().valueRadians() ) ;
    Sous Visual express 2008 la compilation et l’exécution se déroule bien.
    Sous Mingw la compialtion échoue et m'affiche le message suivant :
    error: no matching function for call to 'GetRadianAngleModulo(Ogre::Real)'
    ( Ogre::Real est le type float )

    Voici ma version de Mingw :
    === TDM-GCC Compiler Suite for Windows ===
    --- GCC 4.4/4.5 Series ---
    *** Standard MinGW 32-bit Edition ***

    ...

    REQUIRED BASE:
    * gcc-core (gcc-4.5.2-tdm-1-core)
    * binutils (binutils-2.21-3-mingw32-bin)
    * mingwrt (mingwrt-3.18-mingw32-dev, mingwrt-3.18-mingw32-dll)
    * w32api (w32api-3.17-2-mingw32-dev)
    Peut être qu'il y a une fonction existante pour faire ce travail. Si oui je suis tout même intéresser par la résolution de cette erreur.

    Merci d'avance .

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    As-tu essayer de mettre Ogre::Real à la place de float dans les arguments templates ?
    Voir message de 3DArchi.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Citation Envoyé par C++11
    A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
    — integral or enumeration type,
    — pointer to object or pointer to function,
    — lvalue reference to object or lvalue reference to function,
    — pointer to member,
    — std::nullptr_t.
    (en C++03, la différence est que std::nullptr_t n'existe pas et les références ne sont pas précisées lvalue mais les restrictions sont pour le reste identiques)

    Un paramètre générique (non type) doit donc être un de ceux précisés dans la norme ci-dessus. Ce qui ne saurait être le cas d'un float

    Bref ton code est invalide car il est interdit d'avoir une quelconque fonction générique f<float valeur>
    My 2 cents :
    • ca ne résout pas ton problème mais par habitude, je préfère mettre les types déductibles à la fin pour ne pas avoir à les spécifier :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      template< T inOrigine, T inModulo,typename T >
      T Ca::Math::GetRadianAngleModulo( T inRadianAngle );
      //...
      Ca::Math::GetRadianAngleModulo<1,2>(3);
    • en C++11, tu pourrai faire quelque chose comme ça (mais je me pince un peu le nez pour te présenter ce hack) :
      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
      template< typename T, typename inOrigine, typename inModulo >
      T GetRadianAngleModulo( T inRadianAngle )
      {
          T aAlpha = std::atan2( std::sin( inRadianAngle ), std::cos( inRadianAngle ) ) ;
       
      	aAlpha += inModulo::value ;
       
          // http://pubs.opengroup.org/onlinepubs/007904975/functions/fmod.html
          T aY = inOrigine::value + inModulo::value ;
      	return aY ? std::fmod( aAlpha, inOrigine::value + inModulo::value ) + inOrigine::value : aAlpha + inOrigine::value ;
      }
       
      template<class T>
      struct param_1
      {
          static constexpr T value = 1.;
      };
       
      template<class T>
      struct param_2
      {
          static constexpr T value = 2.;
      };
       
      // ....
      GetRadianAngleModulo<float,param_1<float>,param_2<float>>(1.0);
    • passe en paramètre :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      template< typename T >
      T GetRadianAngleModulo( T inRadianAngle, T inOrigine, T inModulo );
       
      // puis : 
      float aResult = Ca::Math::GetRadianAngleModulo( m_SurfaceNode->getOrientation().getYaw().valueRadians(),0, 6.2831853071795f ) ;
    • Mais en réalité, quel est l'intérêt de rendre cette fonction générique ??? Laisse jouer la conversion :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double GetRadianAngleModulo( double inRadianAngle, double inModulo, double inOrigine)
      ou à la place de double un typedef au bon endroit pour fixer une fois pour toute ton type 'real'

  4. #4
    Membre éclairé Avatar de Suryavarman
    Homme Profil pro
    Développeur 3D
    Inscrit en
    Mai 2006
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur 3D
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2006
    Messages : 233
    Par défaut
    Belle réponse

    J'espérais faire un typedef de cette fonction pour un type et un intervalle particulier pour plus d'une utilisation de celle-ci. Ce qui aurait été élégant je trouves.

    Mais c'est finalement plus contraignant qu'autres choses.

    Avec l'intervalle passé en template je ne peux pas utilisé ma fonction GetPi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template < typename T >
    T Ca::Math::GetPi()
    {
        return std::atan2( static_cast<T>( 0 ), static_cast<T>( -1 ) ) ;
    }
    Ce qui m'oblige à définir la constante en dure. Ce qui est encore acceptable si un typedef viens définir GetRadianAngleModulo.

    Je vais donc opter pour la solution par passage de paramètre. Mais je ne vais pas laisser la conversion se faire, ça remettrait en cause toute ma librairie Math qui n'est que du template ( cf : GetPi ).

    Merci beaucoup pour la réponse. Elle est très claire et complète.

    Remarques :
    par habitude, je préfère mettre les types déductibles à la fin pour ne pas avoir à les spécifier :
    C'est donc comme ça qu'il faut faire. Merci ça m'avait titillé l'esprit.

  5. #5
    Membre éclairé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Par défaut
    Bonjour,
    utilisant quelques fois la forme template<typename T, T value [...]>, la détection automatique de T m’intéressait.
    Citation Envoyé par 3DArchi Voir le message
    ca ne résout pas ton problème mais par habitude, je préfère mettre les types déductibles à la fin pour ne pas avoir à les spécifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template< T inOrigine, T inModulo,typename T >
    T Ca::Math::GetRadianAngleModulo( T inRadianAngle );
    //...
    Ca::Math::GetRadianAngleModulo<1,2>(3);
    Mais je pense que cela pose un problème de "scope" .
    Citation Envoyé par norme
    The potential scope of a template parameter name begins at its point of declaration (3.3.2) and ends at the
    end of its declarative region. [ Note: This implies that a template-parameter can be used in the declaration
    of subsequent template-parameters and their default arguments but cannot be used in preceding template-parameters
    or their default arguments. For example,

    template<class T, T* p, class U = T> class X { /* ... */ };
    template<class T> void f(T* p = new T);
    This also implies that a template-parameter can be used in the specification of base classes. For example,
    template<class T> class X : public Array<T> { /* ... */ };
    template<class T> class Y : public T { /* ... */ };

    The use of a template parameter as a base class implies that a class used as a template argument must be
    defined and not just declared when the class template is instantiated. —end note ].

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par gb_68 Voir le message
    Mais je pense que cela pose un problème de "scope" .
    Exact. Je n'avais pas fait attention que dans ce cas cela ne s'y prêtait pas.

  7. #7
    Membre éclairé Avatar de Suryavarman
    Homme Profil pro
    Développeur 3D
    Inscrit en
    Mai 2006
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur 3D
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2006
    Messages : 233
    Par défaut
    Je suis curieux et je n'arrive pas à comprendre le problème de portée .

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

Discussions similaires

  1. [Templates] Quel système utilisez-vous ? Pourquoi ?
    Par narmataru dans le forum Bibliothèques et frameworks
    Réponses: 270
    Dernier message: 26/03/2011, 00h15
  2. Réponses: 2
    Dernier message: 17/10/2007, 09h24
  3. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  4. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  5. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

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