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 un type inconnu (templates?)


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Points : 57
    Points
    57
    Par défaut Fonction qui retourne un type inconnu (templates?)
    Bonjour,

    J'ai besoin d'une fonction qui laisse le choix à l'utilisateur de créer une variable de type maClasse, et dans ce cas la renvoie par un return, ou si l'utilisateur en decide autrement, la fonction renvoie un int.

    Le code ci dessous ne compile pas et j'ignore pourquoi. (il ne se sert même pas du destructeur d’ailleurs. Pourquoi?)

    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
    #include <iostream>
    #include <stdio.h>
    using namespace std;
     
     
    class maClasse
    {
     
    public:
        int a;
        maClasse()
        {
            a=555;
            cout << "constructeur\n";
        }
        ~maClasse()
        {
            cout << "destructeur\n";
        }
     
    template <class maClasse>
    maClasse TestRetour()
    {
        return 1;
    }
    };
     
    main()
    {
    maClasse *C = new maClasse;
     
    cout << C->a << endl;
    C->TestRetour();
     
    }
    Quelqu'un pourrait m'aider a me servir des templates?

    Une autre solution existe peut être?

    Merci par avance

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Il faut que le compilateur puisse savoir quel argument est passé au template :
    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
    template <typename T>
    void foo(void)
    {
            //....
    }
     
    foo<int>();
     
    // ou
    template <typename T>
    void foo(T a)
    {
             // ....
    }
    foo(45);

  3. #3
    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 B65AcR Voir le message
    Le code ci dessous ne compile pas et j'ignore pourquoi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <class maClasse>
    maClasse TestRetour()
    {
        return 1;
    }
    Ça ne compile pas parce qu'un int (1) n'est pas convertible en "maClasse".

    Citation Envoyé par B65AcR Voir le message
    il ne se sert même pas du destructeur d’ailleurs. Pourquoi?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maClasse *C = new maClasse;
    Le destructeur sera appelé lors d'un delete C;.
    (Attention aux fuites mémoire)

    Citation Envoyé par B65AcR Voir le message
    J'ai besoin d'une fonction qui laisse le choix à l'utilisateur de créer une variable de type maClasse, et dans ce cas la renvoie par un return, ou si l'utilisateur en decide autrement, la fonction renvoie un int.
    J'ai pas l'impression que les templates soient utiles pour ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    maClasse testRetour(const maClasse& arg) const {
         return arg; // copie ici, je me demande si dans ce cas particulier retourner une ref constante est safe.
    }
     
    int testRetour() const {
         return 1;
    }
    Tu as au final 2 fonctions bien distinctes : 1 qui prend un "maClasse en argument et 1 qui ne prend pas d'argument.

    Ou peut être que tu cherches à faire quelque chose comme
    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
    template <class T>
    T createOrReturnInt() const;
     
    template <>
    int createOrReturnInt<int>() const {
        return 1;
    }
     
    template <>
    maClasse createOrReturnInt<maClasse>() const {
        return maClasse();
    }
     
    // niveau utilisation
    maClasse a;
    auto b = a.createOrReturnInt<int>(); // b de type int
    auto c = a.createOrReturnInt<maClasse>(); // c de type maClasse
    auto d = a.createOrReturnInt<float>(); // erreur de link
    Mais j'ai du mal à voir l'intéret d'une telle fonction.

    En créant la fonction différemment on peut arriver à quelque chose du genre
    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
    class maClasse {
    public:
    	int a;
    	maClasse(): a(555) { std::cout << "constructeur\n"; }
    	~maClasse() { std::cout << "destructeur\n"; }
     
    	template <bool>
    	struct createOrReturnInt {
    		static int exec() { return 1; }
    	};
     
    	template <>
    	struct createOrReturnInt<true> {
    		static maClasse exec() { return maClasse(); }
    	};
    };
     
    // utilisation
    auto a = maClasse::createOrReturnInt<true>::exec(); // a de type maClasse
    auto b = maClasse::createOrReturnInt<false>::exec(); // b de type int
    C'est peut être ce que tu cherches à faire ?

  4. #4
    Membre du Club
    Homme Profil pro
    touristepationné
    Inscrit en
    Janvier 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 132
    Points : 57
    Points
    57
    Par défaut
    Merci pour vos réponses très complète.

    Si on cré 2 fonctions surchargées, est-ce bien utile de passer par les templates?

    Là ce n'était qu'un bout de code de test. la vrai fonction proposera a l'utilisateur de créer une classe et de l'ajouter a un vecteur, choix qu'il pourra refuser. j'ai alors besoin de connaitre sa decision par le renvoit d'un booleen ou autre.

    La solution que j'ai pour l'instant trouvé est de faire un push vers le vecteur si la variable est crée.

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par B65AcR Voir le message
    Si on cré 2 fonctions surchargées, est-ce bien utile de passer par les templates ?
    Oui, parce que pour faire une surcharge, il faut que les signatures des fonctions diffèrent par leurs arguments.
    Or, le type de retour ne fait pas partie de la signature. Celles-ci sont donc identiques pour les deux fonctions.

    Voir cette entrée de la FAQ.

  6. #6
    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 B65AcR Voir le message
    la vrai fonction proposera a l'utilisateur de créer une classe et de l'ajouter a un vecteur, choix qu'il pourra refuser. j'ai alors besoin de connaitre sa decision par le renvoit d'un booleen ou autre.
    Il est du coup inutile de retourner un type inconnu, c'est un simple if
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    bool askUser() {
       std::cout << "add ? (o/n)";
       char c;
       std::cin >> c;
       return c == 'o';
    }
     
    void addIfUserWant(std::vector<maClasse>& vec) {
        if(askUser()) {
            vec.emplace_back(/* ... */);
        }
    }

Discussions similaires

  1. Fonction qui retourne n'importe quel type
    Par andromeda dans le forum C++
    Réponses: 24
    Dernier message: 25/02/2014, 16h47
  2. Fonction qui retourne un type anonyme
    Par Pelote2012 dans le forum Entity Framework
    Réponses: 1
    Dernier message: 14/10/2011, 12h24
  3. fonction qui retourne plusieurs types
    Par nouvelinscrit dans le forum C#
    Réponses: 4
    Dernier message: 19/07/2010, 16h00
  4. Réponses: 2
    Dernier message: 16/03/2009, 14h37
  5. Fonction divisant argument de type inconnu
    Par Nasky dans le forum C
    Réponses: 9
    Dernier message: 29/07/2003, 00h32

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