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 :

les fonction template


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 32
    Points : 30
    Points
    30
    Par défaut les fonction template
    bonjour tout le monde
    j'ai une fonction somme qui fait la somme des deux nombre quelconque voila la déclaration de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template<class T1,class T2>
    T1 somme(T1 a,T2 b){
        return a+b;
        }
    le problème c'est que le type de retour dépend toujours du nombre a
    lorsque j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <iostream>
    using namespace std;
    template<class T1,class T2,class T>
    T somme(T1 a,T2 b){
        return a+b;
        }
    int main()
    {
        double a=somme(12,12.6);
        return 0;
    }
    une erreur :
    D:\c++SMI6\exercice2\main.cpp|15|error: no matching function for call to `somme(int, double)'|
    merci de m'aider

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Salut

    ça devrait être de ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    using namespace std;
    template<class T,class T1,class T2>
    T somme(T1 a,T2 b){
        return a+b;
        }
    int main()
    {
        double a=somme<double>(12,12.6);
        return 0;
    }

  3. #3
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Le problème c'est qu'en général, '+' est associé à un groupe (ou au moins monoïde) au sens Mathématique. Et l'une des caractéristiques principales, c'est que quand tu additionnes deux éléments :
    - les deux appartiennent au même ensemble
    - le résultat appartient au même ensemble
    (on parle de stabilité de '+')

    Donc, ne serait-il pas mieux ici d'avoir un signature de ce genre (auquel cas tu n'auras plus besoin de préciser le type de retour à la main car le compilateur ne peut pas le déduire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename T>
    T add(T t1, T t2);
    ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut,

    A mon avis, le problème vient du fait que dans

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template<class T1,class T2,class T>
    T somme(T1 a,T2 b){
        return a+b;
        }
    Ton compilateur n'a aucune idée du type T qu'il doit renvoyer quand tu lui passes un int et un double : somme(12,12.6); : 12 est un int, 12.6 un double, mais le retour, oui c'est un T, mais quoi? C'est pour cela qu'il chouine.

    Je pense que tu devrais choisir T=T1, comme ca tu respectes l'associativité naturelle de l'addition. Le problème, c'est qu'alors somme(12, 12.6)=24. Sinon, tu peux forcer T comme double... oui mais somme(12,12)=24.0 (double)

    Francois

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Alp Voir le message
    Et l'une des caractéristiques principales, c'est que quand tu additionnes deux éléments :
    - les deux appartiennent au même ensemble
    - le résultat appartient au même ensemble
    (on parle de stabilité de '+')
    Ne peut on pas additionner deux types différents en C++ (le compilateur caste comme il faut, non?). Et +, en informatique, c'est pour un groupe, pas un monoide, puisque les flottants sont signés, et tout élément d'un type entier a un inverse.

    Enfin, quand je dis un groupe (ou un monoide), c'est pour les types entiers, seulement: l'addition en virgule flottante n'est pas associative.

    Francois

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par Alp Voir le message
    Donc, ne serait-il pas mieux ici d'avoir un signature de ce genre (auquel cas tu n'auras plus besoin de préciser le type de retour à la main car le compilateur ne peut pas le déduire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename T>
    T add(T t1, T t2);
    ?
    Salut,

    Ton code est plus simple que le mien mais dans le cas où les types de t1 et t2 sont différents, il y aura toujours besoin de préciser T (mais, c'est vrai, dans le cas d'égalité y'a pas besoin)

  7. #7
    Alp
    Alp est déconnecté
    Expert éminent sénior

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Je remettais simplement en question l'utilité de fournir la possibilité d'avoir T1 et T2 différents, avec un troisième type T pour le retour.
    Ca dépend des types que va donner le PO à sa fonction.

    M'enfin qu'il s'agisse de vecteurs, de matrices, de nombres, on veut souvent T1 = T2 = T.

    Après, ça peut être une exception ici

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mai 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 32
    Points : 30
    Points
    30
    Par défaut
    merci

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Le problème initial est impossible à résoudre en C++98, en tout cas c'est ce que semble expliquer la proposition pour ajouter l'opérateur decltype pour le C++0x.

    The return type of a generic function often depends on the types of the arguments. In some cases the dependency can
    be expressed within the current language. For example:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class T>
    T min(const T& a, const T& b) { return a < b ? a : b; }
    In other cases this is not as easy, or even possible. Consider the following example:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class A, class B>
    R add(const A& a, const B& b) { return a + b; }}
    The return type, denoted here with R, should be the type of the expression a + b. That type may, however, be A, B,
    or something entirely different. In short, the type R depends on the types A and B in a way that is not expressible in
    today’s C++.
    Grâce à decltype, dans un monde idéal, on pourrait alors écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<class A, class B>
    decltype(a+b) add(const A& a, const B& b) 
    { 
       return a + b; 
    }
    Malheureusement, ce n'est pas possible, car, si j'ai bien compris, les parseurs de C++ lisent le code de gauche à droite donc les variables "a" et "b" ne sont pas encore déclarées au moment où le parseur lit "decltype(a+b)"...

    Il a donc fallu trouver une autre syntaxe...
    Vous êtes bien assis ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<class A, class B>
    auto add(const A& a, const B& b) ->  std::decltype(a+b)
    { 
       return a + b; 
    }
    Et oui, en C++0X le type de retour d'une fonction pourra être à droite ! Et ce sera vrai partout.
    Cette définition de fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    auto estPair(int i) -> bool
    {
       return i%2;
    }
    sera valide en C++0x

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    A quand le C++0X sur windows? ^^

  11. #11
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    La bêta de VS2010 implémente déjà pas mal de features. Notamment les lambda expressions qui elle aussi voit leur type de retour indiqué à droite .
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 16
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 57
    Points : 65
    Points
    65
    Par défaut
    Merci!

    http://herbsutter.wordpress.com/2009...now-available/

    Apparemment y'a aussi les decltype:

    C++0x features, check out the lambda functions (my fave), move-semantic rvalue references, the new auto, its good friend decltype, and the ever-helpful static_assert.

  13. #13
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Une "solution" applicable aujourd'hui consiste à passer par une classe de traits, où l'on spécifie explicitement le type de retour que l'on veut en fonction de toutes les combinaisons de type des arguments que l'on s'attend à trouver.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/09/2014, 11h51
  2. Réponses: 4
    Dernier message: 09/09/2010, 18h14
  3. doc sur les fonctions
    Par masterfab dans le forum C
    Réponses: 18
    Dernier message: 23/06/2005, 17h55
  4. [Postgresql]Problème avec les fonctions ...
    Par fet dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/10/2003, 09h04
  5. Réponses: 7
    Dernier message: 24/05/2003, 15h56

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