Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1357 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C++] qsort() sur des templates

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] qsort() sur des templates

n°1217141
_Raynor_
Posté le 06-10-2005 à 23:05:09  profilanswer
 

Bonsoir,
 
Dans ma classe Map, j'ai une méthode de tri (pour trier un tableau de taille fixe connue) dont voici le code :

Code :
  1. template <typename Enreg>
  2. void Map<Enreg>::_tri(void) {
  3. // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_qsort.asp
  4. qsort(
  5.  (void *)this->Liste, // Le tableau contenant des MapModule<Enreg>
  6.  this->nb_enreg, // Le nombre de cellules du tableau
  7.  this->sizeof_MapModule, // La taille d'un MapModule<Enreg> (obtenue avec sizeof())
  8.  Map_comparaison_croissant<Enreg> // Ma fonction de tri
  9. );
  10. }


Et la fonction de tri est :

Code :
  1. template <typename Enreg>
  2. int Map_comparaison_croissant(const void *element1, const void *element2) {
  3. return strcmp((*(MapModule<Enreg>*)element1).get_cle(), (*(MapModule<Enreg>*)element2).get_cle());
  4. }


Et là où j'ai un problème c'est que Visual C++ 6.0 me dit :

Citation :

classes-map.h(192) : error C2664: 'qsort' : cannot convert parameter 4 from 'int (const void *,const void *)' to 'int (__cdecl *)(const void *,const void *)'


J'ai bien essayé de mettre, à tout hasard, (__cdecl *) (un cast) devant le 4ème argument de qsort ("Map_comparaison_croissant<Enreg>" ), mais il me sort un : syntax error : '__cdecl'.
 
J'ai fait des tests et j'arrive à faire fonctionner un qsort tant que la fonction de comparaison n'est pas sur un type générique.
Est-ce peine perdue ?

mood
Publicité
Posté le 06-10-2005 à 23:05:09  profilanswer
 

n°1217185
Taz
bisounours-codeur
Posté le 06-10-2005 à 23:59:17  profilanswer
 

pas de sqort. utilise std::sort

n°1217186
_Raynor_
Posté le 07-10-2005 à 00:02:46  profilanswer
 

Je comprends pas ?
Je ne peux pas employer le tri rapide dans ce cas là ?
 
Qu'est-ce que std::sort ? (je ne suis pas encore très très familier avec toutes les librairies C/C++).

n°1217195
Taz
bisounours-codeur
Posté le 07-10-2005 à 00:27:52  profilanswer
 

std::sort c'est le tri C++. qsort c'est du C avec tous ses défauts.

n°1218124
jesus_chri​st
votre nouveau dieu
Posté le 07-10-2005 à 23:23:46  profilanswer
 

et de toute façon pour obtenir l'adresse d'une méthode le & devant est obligatoire. Il est optionnel pour les fonctions globales "à la C".
 
Mais Taz a raison, en C++ il faut utiliser std::sort qui marche avec des itérateurs. Sachant qu'un pointeur est un itérateur, c'est pas trop contraignant. Les algos présents dans le C++ sont bien + nombreux que ceux du C. D'ailleurs en C, à part qsort...
 
exemple :

Code :
  1. int tab[] = {2, 42, -6, 45 };
  2. std::sort(tab, tab + 4);


 
le tri se fait avec l'operator< par défaut.
 
edit : ta fonction de comparaison semble bien être un fonction et pas une méthode. Dans ce cas :

Code :
  1. // edit : après remarque de Taz, ce code n'est pas bon car cette fonction est templatée. Sans template ça marcherait
  2. extern "C"
  3. {
  4.    template <typename Enreg>
  5.    int Map_comparaison_croissant(const void *element1, const void *element2) {
  6.        return strcmp((*(MapModule<Enreg>*)element1).get_cle(), (*(MapModule<Enreg>*)element2).get_cle());
  7.    }
  8. }
  9. template <typename Enreg>
  10. void Map<Enreg>::_tri(void) {
  11.     // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_qsort.asp  
  12.     qsort(
  13.         (void *)this->Liste, // Le tableau contenant des MapModule<Enreg>  
  14.         this->nb_enreg, // Le nombre de cellules du tableau  
  15.         this->sizeof_MapModule, // La taille d'un MapModule<Enreg> (obtenue avec sizeof())  
  16.         &(Map_comparaison_croissant<Enreg> ) // Ma fonction de tri  
  17.     );
  18. }


devrait marcher à vu de nez. mais ça reste mauvais.

Message cité 1 fois
Message édité par jesus_christ le 13-10-2005 à 21:41:11
n°1218200
Joel F
Real men use unique_ptr
Posté le 08-10-2005 à 09:58:18  profilanswer
 

jesus_christ a écrit :


Mais Taz a raison, en C++ il faut utiliser std::sort qui marche avec des itérateurs. Sachant qu'un pointeur est un itérateur, c'est pas trop contraignant. Les algos présents dans le C++ sont bien + nombreux que ceux du C. D'ailleurs en C, à part qsort...


 
Sans vouloir sodomiser des dyptéres, il me semble qu'il y a quand même une *légére* différence masi si leur sémantique est identique  :D

n°1218225
Taz
bisounours-codeur
Posté le 08-10-2005 à 11:08:22  profilanswer
 

il sert à quoi ton extern C ?

n°1218467
_Raynor_
Posté le 08-10-2005 à 20:35:01  profilanswer
 

En effet, "Map_comparaison_croissant()" n'est pas une méthode de classe mais bien une fonction.
 
jesus_christ, pour ton exemple, j'obtiens "'std' : is not a class or namespace name", quelle librairie dois-je inclure avant d'utiliser std::sort ?

n°1218472
Taz
bisounours-codeur
Posté le 08-10-2005 à 20:46:53  profilanswer
 

la bibliothèque <algorithm>
 
lis la doc bon sang !

n°1219952
jesus_chri​st
votre nouveau dieu
Posté le 10-10-2005 à 21:23:10  profilanswer
 

Taz a écrit :

il sert à quoi ton extern C ?


à ce que le type du pointeur de fonction soit bien (__cdecl*) sous visual c++
 
Joel F : c'est pas seulement sémantique, les pointeurs sont un cas particulier des itérateurs.
Souvent (avant) vector<T>::iterator était défini comme T*, même si ça ne ce fait plus trop et que ça peut inciter à faire du code pas portable.
Bien sur à part sur les tableaux et les vecteurs* (et dans le sens normal, pas reverse) les pointeurs ne vont pas très loin.
 
* : si les vecteurs stockent de façon contigue, ce qui doit normalement être le cas.

mood
Publicité
Posté le 10-10-2005 à 21:23:10  profilanswer
 

n°1220096
Taz
bisounours-codeur
Posté le 10-10-2005 à 23:33:12  profilanswer
 

j'y comprends rien à votre compilo de merde.

n°1220110
jesus_chri​st
votre nouveau dieu
Posté le 11-10-2005 à 00:16:43  profilanswer
 

visual c++ n'est peut-être pas le compilo le + conforme à l'ISO98 mais c'est un des meilleurs sous win et il a de très loin le meilleur debugger.
Sans compter que VC6 a été écrit en 97 et a donc une bonne excuse pour pas être conforme, quant à VC7 et VC8 il sont très proches du standard. Microsoft a isolé toutes ses "exotismes" dans .net/C# et a laissé le C++ "pur".
 
VC type les fonctions selon leur convention d'appel. __cdecl pour le C, __thiscall pour les méthodes C++, __stdcall pour les appels standard win(utile pour linker avec du VB par exemple, diff sur callee-save et caller-save) et __fastcall pour passer les paramètres par les registres.

n°1220120
Taz
bisounours-codeur
Posté le 11-10-2005 à 02:38:57  profilanswer
 

je m'en fout. extern "C" autour d'un truc C++ c'est un non-sens.

n°1220779
jesus_chri​st
votre nouveau dieu
Posté le 11-10-2005 à 21:15:57  profilanswer
 

c'est pourtant cité dans le Stroustrup. extern défini un linkage et pas un langage -> chap (9.2) En plus son explemple c'est justement le qsort avec une fonction extern "C"

n°1220780
Taz
bisounours-codeur
Posté le 11-10-2005 à 21:29:02  profilanswer
 

justement ... tu ferais mieux de le lire le stroustrup. Du code C++ ne peut avoir un linkage C.

n°1220850
jesus_chri​st
votre nouveau dieu
Posté le 11-10-2005 à 22:55:15  profilanswer
 

j'ai vérifié et il dit bien que toutes les combinaisons sont possible. Et puis du code C++ c'est vite fait, genre

Code :
  1. int f(void)
  2. {
  3.   int a;
  4.   a = 3;
  5.   int b;
  6. }


c'est du C++ et pas du C89, pourtant le linkage extern "C" marche. En cas de template ou de pointeur de méthode, enfin des trucs "très C++" peut-être qu'il n'existe pas de linkage C. Du code C++ peut dans certains cas ne pas être linké en C, mais c'est la plupart du temps possible.
Trouve moi un compilo ou une ligne du Stroustrup qui interdit ça :

Code :
  1. class Bidule
  2. {
  3. public :
  4.    void toto(void) { cout << "toto\\n"; }
  5. };
  6. extern "C" void C_toto(void)
  7. {
  8.    Bidule b;
  9.    b.toto();
  10. }


et on en reparle.


Message édité par jesus_christ le 11-10-2005 à 22:56:23
n°1220855
Taz
bisounours-codeur
Posté le 11-10-2005 à 23:00:24  profilanswer
 

t'as toujours pas lu le stroustrup ça fait plaisir. t'as toujours pas compris à quoi ça servait. laisse tomber.

n°1220859
jesus_chri​st
votre nouveau dieu
Posté le 11-10-2005 à 23:04:27  profilanswer
 

je l'ai sur les genou, le stroustrup 3e edition. Dis moi où il définit les interdictions dont tu parles au lieu de décréter que j'ai pas compris. C'est peut-être vrai, mais argumente.
En attendant l'intro du chapitre 9.2.4 dit bien que la directive extern "truc" sert aussi bien à exporter qu'à importer des symboles de ou vers du C++.


Message édité par jesus_christ le 11-10-2005 à 23:11:04
n°1222141
Taz
bisounours-codeur
Posté le 13-10-2005 à 14:52:40  profilanswer
 

tu ne peux pas obtenir un symbol C++ avec un truc template, c'est ça que je veux dire ...

n°1222423
++fab
victime du syndrome IH
Posté le 13-10-2005 à 19:22:39  profilanswer
 

Taz a écrit :

tu ne peux pas obtenir un symbol C++ avec un truc template, c'est ça que je veux dire ...


Tu fais bien de préciser :)
 
D'ailleurs, j'ai quand même regardé dans la norme, je n'ai trouvé aucun qui paragraphe qui mentionne cette interdiction, même si elle parait logique ... Mais j'ai peut etre pas les yeux en face des trous.

n°1222437
Taz
bisounours-codeur
Posté le 13-10-2005 à 19:41:37  profilanswer
 

c'est pas une interdiction, c'est un non-sens. Tu  ne peux avoir dans un bloc extern "C" que des symboles C. qsort a un linkage C, mais pas besoin de linkage C pour son argument fonction de comparaison.

n°1222439
jesus_chri​st
votre nouveau dieu
Posté le 13-10-2005 à 19:44:01  profilanswer
 

Taz a écrit :

tu ne peux pas obtenir un symbol C++ avec un truc template, c'est ça que je veux dire ...


ah là je suis d'accord, donc mon code est effectivement erroné, on ne peut pas obtenir de symbole C à partir d'un template. Mais on peut à partir d'une fonction C++ passablement proche du C.
 
Fab++ : idem, j'ai lu et relu (le stroustrup, pas la norme), ça ne me semble pas être écrit explicitement. Dans le même genre le fait que les classes locales aux fonctions ne soient pas linkables (même en C++ pur), je l'ai trouvé dans le lexique du site de stroustrup mais pas dans son livre.

n°1222447
jesus_chri​st
votre nouveau dieu
Posté le 13-10-2005 à 19:50:11  profilanswer
 

Taz a écrit :

c'est pas une interdiction, c'est un non-sens. Tu  ne peux avoir dans un bloc extern "C" que des symboles C. qsort a un linkage C, mais pas besoin de linkage C pour son argument fonction de comparaison.

Un symbole C++ ayant un sens en C (ni class ni objet ni template ni pointeur de méthode ni operator...) peut avoir un symbole C, c'est d'ailleur surtout à ça que ça sert.
 
si t'écris void f() {} dans un fichier compilé en tant que C++ c'est du C++ même si ça pourrait exister en C.

n°1222508
++fab
victime du syndrome IH
Posté le 13-10-2005 à 21:11:22  profilanswer
 

Taz a écrit :

c'est pas une interdiction, c'est un non-sens. Tu  ne peux avoir dans un bloc extern "C" que des symboles C. qsort a un linkage C, mais pas besoin de linkage C pour son argument fonction de comparaison.


 
Oui, je voie mal un code C inclure un header dans lequel figure : extern "C" template<class T> void(T);
D'ailleurs, ça parait logique que ce soit mentionné nul part finalement.
Par contre, histoire de couper un cheveux en 4, qsort n'a pas forcément un linkage C ...

n°1222517
Taz
bisounours-codeur
Posté le 13-10-2005 à 21:22:58  profilanswer
 

pourtant c'est le code qui a été proposé.

n°1222529
jesus_chri​st
votre nouveau dieu
Posté le 13-10-2005 à 21:41:44  profilanswer
 

j'ai mis ta remarque dans mon code qui est effectivement erroné. :D

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C++] qsort() sur des templates

 

Sujets relatifs
[C++] Templates en cascadeTemplates et boucles
Spécification de templates imbriquéestemplates et héritage
CMS/templates - Comment utiliser une BD[C++]Héritage de templates, g++ aime pas :(
Génération dynamique de documents paramétrés (templates)[C++] problème de compilation (templates inside)
modification des templatesProblème avec les Templates sous Visual !
Plus de sujets relatifs à : [C++] qsort() sur des templates


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)