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 :

Fonction qui retourne n'importe quel type


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut Fonction qui retourne n'importe quel type
    Bonjour,

    Est-il possible de créer une fonction dans une classe normale qui retourne n'importe quel type ?
    je ne suis pas sur de la syntaxe:

    J'avais pensé aux templates
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    pour la déclaration
    template <typename T>
    T mafonction();
     
    pour la définition
    template <typenameT>
    T mafonction()
    {
       ......
       return i; //i étant un int par exemple
    }
    :

    au niveau utilisation ce serais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int j = mafonction<int>();
    c'est bien cela ?

    Merci de votre aide.

  2. #2
    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 andromeda Voir le message
    Est-il possible de créer une fonction dans une classe normale qui retourne n'importe quel type ?
    Hello,

    Possible via template, attention, pas de définition en 2 temps avec les templates par contre.

  3. #3
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Avec C++11, ta fonction peut retourner un type auto. Petit exemple ici. Sinon comme l'a dit Iradrille, les templates existent aussi.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    Qu'est ce que tu veux dire quand tu dis pas de définition en 2 temps avec les templates ?

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    Pour la définition en deux temps tu veux dire qu'il faut déclarer la méthode et la définition de la méthode dans le meme fichier (par ex: fichier include) je suppose ?

    J'ai fait quelques test avec une methode template mais j'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	Error	1	error C2783: 'T maClasse::maMethode(HWND,UINT,WPARAM,LPARAM)' : could not deduce template argument for 'T'	\mysource.cpp	590
    soit cela viens de la declaration et de la definition de la methode template qui n'est pas bonne ou bien le compilateur s'attend a avoir au moins un parametre avec T dans la méthode.

    Avez vous une idée ?

  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
    Citation Envoyé par imperio Voir le message
    Avec C++11, ta fonction peut retourner un type auto. Petit exemple ici. Sinon comme l'a dit Iradrille, les templates existent aussi.
    Une fonction ne peut pas retourner auto. Tu confond avec la nouvelle syntaxe qui permet d'écrire le type de retour après. On passe de TypeRetour func(); à auto func() -> TypeRetour;.

    andromeda, pas possible de t'aider sans voir plus de code.
    Find me on github

  7. #7
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Une fonction ne peut pas retourner auto.
    Et si, une fonction peut aussi retourner auto. Mais il faut le coupler avec le qualifier decltype. Regardes ici par exemple.
    Si tu souhaites en avoir le coeur net, tu peux tester le code suivant sur un compilo qui supporte c++11:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <typeinfo>
     
    template<class T, class U>
    auto add(T t, U u) -> decltype(t + u) // the return type of add is the type of operator+(T,U)
    {
    	return t + u;
    }
     
    int main()
    {
    	auto a = add(1, 1.2);
    	std::cout << "type of a: " << typeid(a).name() << '\n';
    }
    @andromeda: c'est bien de montrer le message d'erreur - et ce n'est pas du cynisme; beaucoup ne le font pas - mais si tu ne nous donne pas aussi le code auquel il correspond, on ne peut pas deviner d'où vient le problème.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    rod >> C'est exactement ce que jblecanard dit. On ne retourne pas auto, c'est (dans ce cas) juste une syntaxe pour retarder la déclaration du type de retour.

    Ca revient a dire au compilateur.
    Je sais que tu attends un type ici, je vais te donner un joker pour le moment (auto) et le vrai type arrive dans (le truc juste après ->). Et si je respecte pas ce contrat, tu as le droit de m'insulter car le programme sera mal formé.
    andromeda >> Ton erreur vient tu fais que le compilateur n'a pas pu déduire le type template. Il faut bien comprendre que si un type template n'est pas en paramètre dune fonction, le compilateur n'a aucune moyen de le deviner magiquement. Il faut donc l'ecrire explicitement et pour une fonction membre, ca marche comme ca :

    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
    #include <iostream>
    #include <string>
    using namespace std;
     
    struct A
    {
        template <class T> T foo(int)
        {
            return T();
        }    
    };
    int main() {
        A a;
        std::string s=a.foo<std::string>(5);
     
        //marche aussi
        int i=a.foo<decltype(i)>(5);
     
         double d=a.foo<int>(5);
     
         return 0;
    }
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Si la norme C++14 ne change, apparemment on pourra utiliser auto pour les retours fonctions. (ici)

  10. #10
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par darkman19320 Voir le message
    Si la norme C++14 ne change, apparemment on pourra utiliser auto pour les retours fonctions. (ici)
    Ca change rien qu'on ne retourne pas auto. Dans ce que tu présente, auto est juste la pour dire :
    J'ai pas envie d’écrire ce type de retour, tu en sais assez pour le déterminer tout seul alors fait le
    Mais on retourne in fine un type.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  11. #11
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Effectivement, cette modification consiste uniquement en la suppression du trailer decltype.
    Après oui, auto ce n'est qu'un "joker", comme tu dis, mais comment pourrait-il en être autrement en c++?
    Mais grâce à decltype, on peut laisser le compilo décider, c'était le sens de mon intervention.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  12. #12
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Mais on retourne in fine un type.
    Oui je suis tout à fait d'accord avec toi mais je pense que l'on pourra faire quelque chose du style:
    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
    template<typename T>
    auto foo(const T & value)
    {
       //du code
    }
     
    template<>
    auto foo(const Point & value)
    {
       return double(value.x + value.y); //Retourne un double dans ce cas la;
    }
     
    template<>
    auto foo(const UnBeauNobjet & value)
    {
       return Point(value);                   //Retourne un Point dans ce cas ci.
    }
    Je ne vois pas le moment d'autres utilisations que pour éviter d'écrire le type de retour...

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    voici le code la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <typename T>
    	T executeTextView(UINT iMessage, WPARAM wParam = 0, LPARAM lParam = 0) {
    		return TextView::TextViewExecute(_hSelf, iMessage, wParam, lParam);
    	}
    TextView::TextViewExecute est une methode static qui se trouve dans un fichier source textview.cpp et dans une classe.

    le code de TextView::TextViewExecute:

    déclaration dans la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template <typename T>
    	static T TextViewExecute(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
    définition de TextView::TextViewExecute:
    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
     
    template <typename T>
    T TextView::TextViewExecute(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
    {
    	switch (iMessage)
    	{
    	case TXM_GETLENGTH:
    		return SendMessage(hwnd, SCI_GETLENGTH, 0, 0);
     
     
    	default:
    		break;
     
    	}
    	return 1;
    };
    appel de la fonction dans le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int i = executeTextView<int>(TXM_GETLENGTH, 0, 0);
    message d'erreur au niveau de la déclaration et non a l'appel de la méthode comme je fais ci-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Error	1	error C2783: 'T TextView::TextViewExecute(HWND,UINT,WPARAM,LPARAM)' : could not deduce template argument for 'T'	line 198
    l'erreur ce situe a ce niveau là line 198 dans la déclaration de executeTextView:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <typename T>
    	T executeTextView(UINT iMessage, WPARAM wParam = 0, LPARAM lParam = 0) {
    		return TextView::TextViewExecute(_hSelf, iMessage, wParam, lParam);         //<== Erreur line 198 ici
    	}
    Merci de votre aide.

  14. #14
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Peut-être faut-il aider un peu plus le compilo, en ajoutant le type template lors de l'appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return TextView::TextViewExecute<T>(_hSelf, iMessage, wParam, lParam);
    Tiens d'ailleurs, quel compilateur utilises-tu?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    je sur windows x64 j'utilise visual studio 2013.

    en mettant le <T> je n'ai plus d'erreur au niveau de la déclaration ou de la définition, par contre j'ai des erreurs du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Error	15	error LNK2019: unresolved external symbol "public: static int __cdecl TextView::TextViewExecute<int>(struct HWND__ *,unsigned int,unsigned int,long)" (??$TextViewExecute@H@TextView@@SAHPAUHWND__@@IIJ@Z) referenced in function "public: int __thiscall ScintillaEditView::executeTextView<int>(unsigned int,unsigned int,long)" (??$executeTextView@H@ScintillaEditView@@QAEHIIJ@Z)	D:\donnees\dev\VS2013\chatlog\chatmanager\ChatCommands.obj
    cette erreur intervient la ou j'utilise ma fonction si par exemple j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int  getCurrentDocLen()  {		
    		return  executeTextView<int>(TXM_GETLENGTH, 0, 0); 
     
    	};
    et que plus loin dans du code j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int lengthDoc = getCurrentDocLen();
    j'ai les erreurs que j'ai posté ci-dessus.

  16. #16
    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
    As-tu bien mis la définition dans le .h et pas dans le .cpp (pour les templates, c’est obligatoire de mettre la définition dans le .h).

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    oui le code se trouve dans un autre fichier source, je viens de le mettre dans le .h et ca fonctionne, donc le principe des templates fonctionne, apres j'ai des erreurs au niveau fonctionalités mais ca na rien avoir les templates je pense.

    merci a vous tous.

    je met en résolu.

  18. #18
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Personnellement je ne vois toujours aucun intérêt à ce que ma fonction retourne auto.
    A fortiori dans le header, il faut bien que j'indique à l'utilisateur ce que ça retourne, auto ça l'avance pas beaucoup dans la plupart des cas.
    L'optionn "doc" n'étant pas probante amha. Au lieu de "maintenir" le type de retour je devrais maintenir la doc ?!
    Si c'est uniquement dans le cpp, alors ok.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  19. #19
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    J'ai découvert ça hier, et bon, je ne l'ai jamais utilisé dans du vrai code, donc je ne suis pas sûr de moi.
    Mais il me semble que ça peut être utile dans le genre de trucs que j'ai mis en exemple, c'est à dire pour une fonction qui prend plusieurs paramètres templates, qui effectue des opérations dessus et dont on ne sait pas trop quel type va en résulter.
    Je réfléchissais par exemple si ça ne pourrais pas être utile dans une lib que j'ai écrite l'année dernière. C'est une lib de sérialisation au format json (plus quelques outils de manipulations), qui est une surcouche de json_spirit, spécialisée pour un ensemble d'applications de ma boite. Ma lib gère un arbre d'éléments, les éléments sont de types très variés: ça va du type simple (int, double, string), jusqu'au tableau d'objet. Et j'ai rencontré pas mal problème pour gérer cette variété de type sans avoir besoin de faire une fonction par type. Peut-être que ce auto aurait pu m'aider. Je jetterai un coup d'oeil quand j'aurai le temps.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  20. #20
    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
    « auto » comme type de retour permet de faire des choses comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<typename T1, typename T2>
    auto DeuxXPlusY(T1 const& x, T2 const& y) -> decltype(2*x+y)
    {
        return 2*x + y;
    }
    Je ne vois pas de moyen simple de faire ça sans.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Fonction qui retourne plusieurs valeurs !
    Par casafa dans le forum C++
    Réponses: 20
    Dernier message: 23/04/2014, 16h56
  2. Fonction qui retourne un type inconnu (templates?)
    Par B65AcR dans le forum Débuter
    Réponses: 5
    Dernier message: 02/03/2014, 14h07
  3. Fonction qui retourne un type anonyme
    Par Pelote2012 dans le forum Entity Framework
    Réponses: 1
    Dernier message: 14/10/2011, 12h24
  4. fonction qui retourne plusieurs types
    Par nouvelinscrit dans le forum C#
    Réponses: 4
    Dernier message: 19/07/2010, 16h00
  5. Réponses: 2
    Dernier message: 16/03/2009, 14h37

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