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 bon en paramètre de fonction mais pas en sortie


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Par défaut template bon en paramètre de fonction mais pas en sortie
    Bonjour à tous.

    Pourquoi le programme suivant (exercice 8-3 du livre Accelerated C++ ) ne marche pas?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Erreur à la ligne: « double result = median(begin, end); »
    erreur: no matching function for call to ‘median(__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >&, __gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >&)

    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
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <stdexcept>
     
    using namespace std;
     
    template <class It, class T>
    T median(It begin, It end) {
    	if (begin == end) 
    		throw domain_error("median of an empty container");
    	sort(begin, end);
    	--end;
    	while (*begin < *end) {
    		++begin;
    		--end;
    	}
    	return begin != end ? (*begin + *end) / 2 : *begin;
    }
     
    int main() { 
    	vector<double> numbers; 
     
    	numbers.push_back(1); 
    	numbers.push_back(3);
    	numbers.push_back(4);
    	numbers.push_back(5); 
    	numbers.push_back(2);
    	numbers.push_back(6);
     
    	vector<double>::iterator begin = numbers.begin(); 
    	vector<double>::iterator end = numbers.end(); 
     
    	double result = median(begin, end); 
    	cout << result << endl;
    	return 0;
     }
    Ça fonctionne en supprimant « , class T » et en remplaçant T par double, mais je perds la templétisation du renvoie de la fonction.

    Je pensais que la compilation de median avec un type de sortie double se ferait lorsque la ligne « double result = ... » serait vu.

    Même en écrivant la fonction median à part dans un *.h (comme recommandé ici), le problème persiste.

    Message édité pour remplacer « exercice 8-1 » par « exercice 8-3 »

  2. #2
    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,
    La valeur retour d'une fonction n'entre jamais en compte dans une résolution (que ce soit du générique ou de la surcharge). Tu dois alors préciser le second type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    median<vector<double>::const_iterator,double>(begin, end);
    C'est pour ça qu'on précise souvent le type retour comme premier paramètre générique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <class T,class It>
    T median(It begin, It end) {
    Ce qui te permet d'écrire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    median<double>(begin, end);

  3. #3
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    Je n'avais pas fait cet exercice, mais j'ai essayé vos deux propositions et ça marche très bien (sans modifier quoi que ce soit au makefile ou autre manip) :

    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
     #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <stdexcept>
     
    using namespace std;
     
    template < class T, class It>
    T median(It begin, It end) {
      if (begin == end) 
        throw domain_error("median of an empty container");
      sort(begin, end);
      --end;
      while (*begin < *end) {
        ++begin;
        --end;
      }
      return begin != end ? (*begin + *end) / 2 : *begin;
    }
     
    int main() { 
      vector<double> numbers; 
     
      numbers.push_back(1); 
      numbers.push_back(3);
      numbers.push_back(4);
      numbers.push_back(5); 
      numbers.push_back(2);
      numbers.push_back(6);
     
      vector<double>::iterator begin = numbers.begin(); 
      vector<double>::iterator end = numbers.end(); 
     
      double result = median<double>(begin, end); 
      cout << result << endl;
      return 0;
    }

  4. #4
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    @goran kajfes
    Cela dit je n'avais pas du tout compris l'exercice comme toi.

    L'énoncé disait ceci :

    Note that the various analysis functions we wrote in §6.2/110 share the same behavior;
    they differ only in terms of the functions they call to calculate the final grade. Write a template function, parameterized by the type of the grading function, and use that function to evaluate the grading schemes.
    Les 'various analysis functions' dont il est question me semblaient être
    p113 :
    - double median_analysis(const vector<Student_info& students);
    p. 115 :
    - double average_analysis(const vector<Student_info& students);
    qui en effet ont mêmes types d'arguments et même type de valeur de retour et aussi même code à la seule différence que l'une appelle, indirectement, la fonction grade_aux et l'autre la fonction average_grade, comme arguments de transform().

    Il me semblait que le template à trouver était une sorte de généralisation de ces deux fonctions (utilisées l'une et l'autre dans le main() de la page 114).
    Il y a aussi, il est vrai, optimistic_median_analysis p 116, mais son code est un peu différent et je ne sais pas trop si on pourrait aussi l'intégrer d'une manière ou d'une autre dans le même template.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Par défaut
    @3DArchi: merci. Ça m'a été très utile. Je me suis servi de tes conseils pour résoudre d'autres exercices. Je crois que tout ce que tu as dit là n'est pas abordé dans le chapitre 8 (ou alors, je suis très tête-en-l'air). Pour tester la performance de cette fonction par rapport à son équivalent sans itérateur (en transmettant directement le vecteur en paramètre de la fonction), j'ai repris le fichier source main2.cc du chapitre 4 et ai appliqué l'exécutable sur un fichier de 10000 étudiants. Les performances sont à peu près identiques. J'ai du supprimer quelques const en paramètres de fonctions (obligé à cause du sort() de median() car on ne passe plus par une copie du vecteur).

    @ptyxs: mea culpa. Il s'agissait de l'exercice 8-3, et pas du 8-1.
    Il me semblait que le template à trouver était une sorte de généralisation de ces deux fonctions (utilisées l'une et l'autre dans le main() de la page 114).
    Pour résoudre ce dernier, j'avais simplifié les 3 fonctions analysis (ainsi, elles ne contiennent plus qu'une seule ligne de code) en créant une nouvelle fonction (je crois que c'était la solution d'un exo d'un autre chapitre). Ensuite j'ai ajouté des « template <class T> » sur ces 4 fonctions, T remplaçant le type double, et T étant automatiquement remplacé par double à la compilation quand la ligne median(grades) est « vue ». Du moins, c'est ma supposition.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Par défaut
    Citation Envoyé par goran kajfes Voir le message
    Je crois que tout ce que tu as dit là n'est pas abordé dans le chapitre 8 (ou alors, je suis très tête-en-l'air).
    Mince, c'était dans la section Details. Mais ils ne parlent pas de l'ordre imposé des templates.

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

Discussions similaires

  1. Objet existant reconnu dans une fonction mais pas dans une autre
    Par Jiyuu dans le forum Général Python
    Réponses: 0
    Dernier message: 20/09/2011, 18h19
  2. Probleme CSS: Bon affichage menu sur Firefox mais pas sur IE7
    Par jisko42 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 08/02/2010, 15h08
  3. Réponses: 1
    Dernier message: 03/06/2009, 19h12
  4. paramètre string fonction -> fonctionne pas toujours?!
    Par francoisvba dans le forum Macros et VBA Excel
    Réponses: 24
    Dernier message: 12/12/2008, 18h08
  5. Réponses: 5
    Dernier message: 02/10/2006, 19h24

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