Pb compat Gcc / VS - C++ - Programmation
Marsh Posté le 13-12-2005 à 23:38:17
Citation : bref, premiere couillonade sous GCC, il veut un "typename" devant MaHashMap <T, T2>::iterator. Je pige pas trop pkoi, mais si je lui met il est content. Par contre la ou ca chie des glacon, c'est plus tard. |
iterator est un nom dépendant (des parametres template T et T2), donc typename est requis vu que iterator est un type. Un compilateur qui implémente 2-phase-lookup a besoin de cette indication pour lever l'ambiguité.
Donc typename MaHashMap<T,T2>::iterator, ou iterator tout court non ?
Pour le reste, édite ton premier poste, je comprend rien aux 2 premieres lignes ...
Marsh Posté le 13-12-2005 à 23:39:15
Et sinon autre pb, sur une autre classe et uniquement avec gcc 2.95 (ca compile sur >=3.0)
un truc style :
Code :
|
(tres joli, merci)
m'envoie un 'anonymous class type not used to declare any objects'
j'ai envie de lui dire 'mange mon caca', mais jsais pas si ca va faire avancer le debat, une idée ? (bon jdois pouvoir refaire remonter l'union d'un cran, genre Union Color, mais je pige pas trop ce qu'il me veut)
Marsh Posté le 13-12-2005 à 23:42:13
Citation : iterator est un nom dépendant (des parametres template T et T2), donc typename est requis vu que iterator est un type. Un compilateur qui implémente 2-phase-lookup a besoin de cette indication pour lever l'ambiguité. |
bin jsais pas, j'ai dev sous VS et je porte la. VS me dit rien, d'ailleurs j'ai toujours ecrit des machins genre :
std::vector<bidule>::iterator
sans avoir besoin de typename ?
Citation : Pour le reste, édite ton premier poste, je comprend rien aux 2 premieres lignes ... |
heuh, j'ai taché, mais redit tjs si tu piges pas
Marsh Posté le 13-12-2005 à 23:58:51
chrisbk a écrit : |
Si bidule est un parametre template, typename est requis, sinon il est interdit.
chrisbk a écrit : |
c'est quoi T2 ? C'est qui la classe de base ?
iterator, c'est typedef typename tr1::unordered_map<T1,T2>::iterator; ou du genre ?
Marsh Posté le 14-12-2005 à 00:02:18
rah putain
Code :
|
(donc bin iterator c'est cui de la hashmap)
Marsh Posté le 14-12-2005 à 00:02:41
ReplyMarsh Posté le 14-12-2005 à 00:06:31
j'ai le meme pb avec
Code :
|
ce qui est un peu pénible.
Edit > bon j'ai nommé ma structure, changer le code la, la et la et tout le monde est content
Marsh Posté le 14-12-2005 à 00:22:07
Moi quand j'utilisais le hash_map de gcc, il fallait fournir soi-même la fonction de hachage :
typedef hash_map<const string, vector<int>, FNV_hash> HachageChaine;
Mais ça a p-ê changé.
Marsh Posté le 14-12-2005 à 00:22:57
bin hasher un enum, jpense y devrait y arriver ? encore que vu l'erreur ca se trouve t'as raison
Marsh Posté le 14-12-2005 à 00:23:46
J'avoue que j'ai un gros doute la-dessus. T'as pas essayé avec un bête int ?
Je sais pas comme VS se démerde, mais la fonction de hachage dépend forcément de ce qu'on utilise comme clé.
Marsh Posté le 14-12-2005 à 00:28:13
Je me demande si il faut pas lui balancer une fonction de hachage dépendant de l'enum justement gnu_cxx::hash<enum>, en clé, et non directemlent l'enum.
Marsh Posté le 14-12-2005 à 00:29:06
ben tu castes la valeur de l'enum en int. C'est un peu crade, mais ça marche.
Marsh Posté le 14-12-2005 à 00:30:46
el muchacho a écrit : ben tu castes la valeur de l'enum en int. C'est un peu crade, mais ça marche. |
bin ecoute, jviens de faire
Code :
|
et la ca me dit
redefinition of struct hash<RXmapEnum::TilesetValue::Tileset> |
donc jsuppose qu'il a une fonction de hash ?
Marsh Posté le 14-12-2005 à 00:30:57
http://gcc.gnu.org/onlinedocs/gcc- [...] med-Fields
Si ca peut aider ...
Marsh Posté le 14-12-2005 à 00:32:30
Non, il y a une déclaration de la fonction de hash qui se trouve dans le header, et qu'il te faut remplir toi-même (enfin j'imagine).
Marsh Posté le 14-12-2005 à 00:33:52
Ca me paraitrait farfelu qu'ilfaille faire ca pour chaque enum (et d'ailleurs ca debloque tjs)
sur cet echec, je vais me pieuter
Marsh Posté le 14-12-2005 à 00:35:02
Ben sinon tu castes la valeur de l'enum en int et basta.
Marsh Posté le 14-12-2005 à 09:03:37
si y'en a qui veulent essayer, vla un bout de code tout laid qui reproduit l'erreur
Code :
|
Marsh Posté le 14-12-2005 à 09:20:28
donc si on rajoute ca au debut :
Code :
|
ca marche mais ca me saoule un peu, quand meme, y'a pas moyen de faire ca de maniere generique ? nan paske ca va etre un peu penible...
Marsh Posté le 14-12-2005 à 10:27:15
Ouais...
1/ Les conteneurs de la STL ne sont pas fais pour être dérivé. En général on évite, en pratique on fait pas.
2/ Les hash_map ne font pas partie du standard, c'est d'ailleurs pour cela qu'avec gcc ces entête sont dans un sous répertoire 'ext' et dans un namespace particulier.
3/ Quand tu parles de VC ou de g++, c'est bien de préciser quelles version. J'en déduis d'au dessus que c'est g++ version 4 ou plus, mais pour VC mystère
4/ gcc 4+ colle plus au standard que VC 7, si gcc pleure alors que VC accepte c'est rarement une erreur du compilo, c'est plutôt une violation du standard.
5/ Un type énuméré n'EST PAS un 'int' en d'autres termes f<int> et f<MonEnum> désignent deux fonctions différentes d'où l'erreur que tu obtiens. Il n'existe pas de fonction de hash correspondant à ton type.
Une solution un peu plus élégante que la tienne est de définir ta propre fonction de hash qui fait la convertion Enum->int
Code :
|
Et de l'utiliser ensuite en lieu et place de la fonction par défaut
Code :
|
Marsh Posté le 14-12-2005 à 10:35:28
Eul' Yannou a écrit : 1/ Les conteneurs de la STL ne sont pas fais pour être dérivé. En général on évite, en pratique on fait pas. |
pour quelles raisons ?
Citation : 2/ Les hash_map ne font pas partie du standard, c'est d'ailleurs pour cela qu'avec gcc ces entête sont dans un sous répertoire 'ext' et dans un namespace particulier. |
ouais, j'ai cru voir, c'est la misere absolue pour utiliser hash_map de maniere portable (et encore, jme cantonne a gcc 2.9 / 3 / 4 et VS 7 / 7.1, sans aller voir d'autre compilo exotiques)
Citation : 3/ Quand tu parles de VC ou de g++, c'est bien de préciser quelles version. J'en déduis d'au dessus que c'est g++ version 4 ou plus, mais pour VC mystère |
Yep, désolé.
gcc : 2.96 / 3.x / 4.x
VS : 7.1
Citation : 4/ gcc 4+ colle plus au standard que VC 7, si gcc pleure alors que VC accepte c'est rarement une erreur du compilo, c'est plutôt une violation du standard. |
en l'occurence, hash_map n'etant comme tu le dis pas standard, ca ne joue que peu ici. J'ai plus de probleme de VS7.1 a gcc 2.96 que de VS7.1 a gcc3 / 4 (genre gcc 2.96 vient de me pleurer dans les bras car il ne connait pas std::ios::pos_type, alors que cela ne perturbe nullement ses frangins)
Citation : 5/ Un type énuméré n'EST PAS un 'int' en d'autres termes f<int> et f<MonEnum> désignent deux fonctions différentes d'où l'erreur que tu obtiens. Il n'existe pas de fonction de hash correspondant à ton type. |
ouais bin je prefere la solution a VS qui permet d'eviter ce genre de truc casse tete.
Citation : Une solution un peu plus élégante que la tienne est de définir ta propre fonction de hash qui fait la convertion |
j'ai fait un truc dans le genre, je regarderais en detail les differences plus tard. (par contre ton truc marchera pas sous gcc 2.96, question de namespace differents C'est vraiment la chienlit les hash_map en c++). Ta solution m'embete un peu car jme demande ce que VS me dira dessus, mais jverrais bien
Merci pour ta réponse
Marsh Posté le 14-12-2005 à 10:53:02
Citation : pour quelles raisons ? |
Principalement parce qu'on a jamais besoin de le faire.
Quelles fonctionnalité rajoutes-tu à une hash_map dans ton projet ?
Une règle de base pour un bon design est de préférer l'agrégation à l'héritage quand c'est possible.
En terme d'implémentation, les conteneurs de la STL ne sont pas prévu pour être dérivés.
Aucune de leurs fonctions membres ne sont redéfinissable, et leur destructeur n'est pas 'virtual'.
Citation :
|
gcc 2.96 est un compilateur exotique. C'est une sous branche de je ne sais trop quoi, développée pour d'obscures raisons dont aucunes n'était technique. Quasiment aucun projet ne le supporte.
Citation :
|
Je ne disais pas ça pour les hash_map, mais pour le fait que gcc 4+ t'oblige à n'employer que des noms qualifiés dans les templates par exemple, et surtout pour le fait qu'il ne fait pas de conversion implicite d'un enum vers un int.
Quant à gcc 2.96, cf ma remarque précédente.
Citation :
|
Dans ce cas peut-être, mais il y a des raisons de ne pas le faire. C++ est un langage fortement typé.
Citation : j'ai fait un truc dans le genre, je regarderais en detail les differences plus tard. (par contre ton truc marchera pas sous gcc 2.96, question de namespace differents C'est vraiment la chienlit les hash_map en c++). Ta solution m'embete un peu car jme demande ce que VS me dira dessus, mais jverrais bien |
Tu peux t'en sortir avec des alias de namespace et un peu de compilation conditionnelle.
Marsh Posté le 14-12-2005 à 10:57:45
Eul' Yannou a écrit :
|
bin rien, si ce n'est de n'avoir plus a me casser la tete sur la desalloc a la fin.
Citation : |
bin je le croise pourtant frequemment ? ou alors y'a de grosses variations 2.95 / 2.96 ?
Citation : Je ne disais pas ça pour les hash_map, mais pour le fait que gcc 4+ t'oblige à n'employer que des noms qualifiés dans les templates par exemple, et surtout pour le fait qu'il ne fait pas de conversion implicite d'un enum vers un int. |
il ne fait pas de conversions implicite enum => int, il utilise seulement une autre facon de faire le hachage qui fait que ca marche (sans conversion implicite)
Citation : Dans ce cas peut-être, mais il y a des raisons de ne pas le faire. C++ est un langage fortement typé. |
cf au dessus
Eul' Yannou a écrit : [quote] |
justement non. Gcc 2 ne supporte pas l'aliasing sur std (namespace de la hashmap dans cette version), faut passer par #define, et gcc 3 rale si j'utilise un alising plutot que __gnu_cxx (dans le cas de la specialisation partielle de hash<> )
donc compilation conditionnelle et agressage momoche au #define
Marsh Posté le 14-12-2005 à 11:04:01
Citation : bin rien, si ce n'est de n'avoir plus a me casser la tete sur la desalloc a la fin. |
Dsl, j'ai pas suivi.
Citation : ou alors y'a de grosses variations 2.95 / 2.96 ? |
Oui, malheureusement je ne me souviens plus exactement, mais 2.96 est connu pour créer un max de problème.
Citation : ustement non. Gcc 2 ne supporte pas l'aliasing sur std (namespace de la hashmap dans cette version) |
Alors je ne vois plus qu'une jolie file de #define englobant des typedefs.
Pas terrible, mais j'ai rien d'autre en stock.
Marsh Posté le 14-12-2005 à 11:08:14
Eul' Yannou a écrit :
|
tout ca pour dire qu'il faut etre bien motivé pour faire du portable. Y'a aussi plein de petit gag debiles entre gcc 2.9 et gcc 3, ca pete bien les burnes (sans parler de VS7.0 qui a un peu de mal)
Marsh Posté le 14-12-2005 à 11:22:46
J'en oublie la question première de ton post, à savoir comment détruire les élements d'une hash_map.
Personnellement, je préfère un foncteur et un foreach, ça m'évite pas mal de boucles.
Code :
|
Marsh Posté le 14-12-2005 à 11:26:39
Citation : tout ca pour dire qu'il faut etre bien motivé pour faire du portable. Y'a aussi plein de petit gag debiles entre gcc 2.9 et gcc 3. |
En pratique, ça se passe pas trop mal quand même, tant que tu ne dois pas supporter des vieux compilos.
Le meilleurs système, je trouve c'est de compiler en gcc 4 avec les options "-ansi -pedantic -Wall", ça lève un bon paquet de truc non portable. Puis ensuite de passer le code sur les autres compilos.
Utiliser CMake aussi, c'est une super idée dans ce cas.
Marsh Posté le 14-12-2005 à 23:40:14
Hop, je reviens sur ce topic.
chrisbk a écrit : |
Comme le dit Yannou, gcc 2.96 n'est pas une version "offcielle" de gcc, c'est je crois une version hackée par Redhat pour leurs propres besoins. Perso, je ne recommande pas trop, elle peut poser des pb et d'ailleurs pas mal de packages se vautrent à la compilation avec cette version. Les vrais versions pré-3 sont la/es dernière(s) 2.95 (2.95.4 il me semble). Elles sont tout-à-fait acceptables pour du code de production (c'est ce que nous utilisons pour des produits vendus de dizaines de milliers de $), mais pas très à jour niveau respect du standard.
Après, il vaut mieux éviter toutes les versions avant la 3.3.2, pas trop stables, et si possible attaquer direct une 3.4.x, x>=2 par ex, qui est probablement la plus stable et proche du standard pour la production (je n'ai jamais travaillé avec une 4.xx).
Marsh Posté le 14-12-2005 à 23:43:18
ouais 2.95 a un peu de mal, elle vient de me faire un gag sur l'acces d'une classe nested aux membres privées de sa classe "parent", c'est un brin relou
Marsh Posté le 14-12-2005 à 23:46:46
Avec les 2.95, il ne faut pas chercher à faire des trucs trop sioux, elles ne supportent pas, et limiter l'utilisation de templates au plus basique. Faut bien voir que le standard C++ n'était pas encore figé à cette époque.
Marsh Posté le 14-12-2005 à 23:52:19
Normalement, ça ne devrait pas poser trop de pb, à part :
- templates (si lourdement utilisés),
- namespaces,
- et évidemment les hash_maps, vu qu'il n'y a pas 2 interfaces identiques.
edit : et les pragmas, et le code asm...
Marsh Posté le 13-12-2005 à 23:14:39
bon, j'ai pas trop envie de chercher, alors ptet qu'un expert GCC saura me dire
Vala, j'ai un truc a porter sous nunux ( + ) et dans ledit truc y'a ca :
(donc le but c'est de faire une hashmap qui efface automatiquement ses valeurs lors de sa destruction. Je sais que ca peut leaker potentiellement gnagna, mais c'est pas le sujet) (enfin si vous avez mieux (sans les smart_ptr a boost), je prends aussi)
bref, premiere couillonade sous GCC, il veut un "typename" devant MaHashMap <T, T2>::iterator. Je pige pas trop pkoi, mais si je lui met il est content. Par contre la ou ca chie des glacon, c'est plus tard.
j'instance ma machine avec :
ca marche niquel sous vs, mais gcc me ponds literalement des pages d'erreurs. Visibelemnt mon ++it lui pose de grave problemes. j'hesite a poster le paquet du message d'erreur car c'est assez glauque. Si je me contente de la derniere ligne, ca rends ca :
/usr/lib/gcc/i486-linux/4.0.0/../../../../include/c++/4.0.0/ext/hashtable.h:596: error: no match for call to (const __gnu_cxx::hash<RXMapEnum::TileSetValue::TileSet> ) (const RXMapEnum::TileSetValue::TileSet& )
et c'est pas super clair
si qqun sait ...
Message édité par chrisbk le 13-12-2005 à 23:40:12