Normalement, tu ne stockes qu'un seul type de données dans une map. La seule
contrainte, c'est que tu ne peux pas le vérifier à la compilation, c'est au
programmeur de faire attention.
Quand j'utilise une map donnée, elle a effectivement un type de clé et un type de valeur bien définis. Le problème reste que je n'ai pas envie d'écrire une structure de map pour chaque paire de types avec lesquels je compte l'utiliser, c'est bien mieux d'avoir une seule définition de map générique... Et avec du void*, à l'utilisation, pas moyen de savoir ce que contient réellement cette map, ce qui fait que C n'est pas très type-safe.
on oblige potentiellement à allouer quelque chose sur le tas
Si pour toi, pointeur == alloué sur le tas, je crois que tu n'as pas bien saisi ce
qu'est un pointeur.
Note le "potentiellement". Si je veux stocker un int dans un vecteur qui dure plus longtemps que mon scope actuel, avec la solution à base de void* je suis bien obligé d'allouer sur le tas de quoi stocker mon int, puisque les adresses sur la pile ne seront pas "valides" suffisamment longtemps. Allouer n'est pas gratuit, surtout dans un langage tel que C.
Effectivement, pour chaque élément ajouté à la map (implémenté avec un arbre
bicolore), tu as déjà 3 pointeurs (fils droit, fils gauche et parent) et
une couleur. Donc, ton économie de bout de chandelle, elle ne change pas grand chose...
Si j'implémente une liste générique et que je l'utilise pour stocker des int, il faut que j'alloue une cellule sur le tas par int ? Et un pointeur n'est pas gratuit, c'est une source possible de cache miss chaque fois que tu le déréférences (alors que si tu stockes l'int dans la cellule de liste, cette cellule est déjà dans le cache).
Sauf que si ta structure contient un pointeur vers une structure allouée
dynamiquement, tu ne sauras jamais quand tu dois la désallouer.
Ca je suis d'accord, mais en général dans une structure on déplace, on ne fait pas vraiment de copie. Si tu veux gérer le cas de la délétion de la structure, 1/ avec des void* le problème se pose aussi, 2/ tu peux donner une fonction "destructeur" au moment de détruire la structure (ou avant), qui se chargera (ou pas) de désallouer ce qu'il faut. Ce problème est inhérent aux langages à gestion manuelle de la mémoire, pas aux templates...
[^] # Re: moar features
Posté par c^3 . En réponse à la dépêche C11 n'est pas encore mort. Évalué à 3.
Quand j'utilise une map donnée, elle a effectivement un type de clé et un type de valeur bien définis. Le problème reste que je n'ai pas envie d'écrire une structure de map pour chaque paire de types avec lesquels je compte l'utiliser, c'est bien mieux d'avoir une seule définition de map générique... Et avec du void*, à l'utilisation, pas moyen de savoir ce que contient réellement cette map, ce qui fait que C n'est pas très type-safe.
Note le "potentiellement". Si je veux stocker un int dans un vecteur qui dure plus longtemps que mon scope actuel, avec la solution à base de void* je suis bien obligé d'allouer sur le tas de quoi stocker mon int, puisque les adresses sur la pile ne seront pas "valides" suffisamment longtemps. Allouer n'est pas gratuit, surtout dans un langage tel que C.
Si j'implémente une liste générique et que je l'utilise pour stocker des int, il faut que j'alloue une cellule sur le tas par int ? Et un pointeur n'est pas gratuit, c'est une source possible de cache miss chaque fois que tu le déréférences (alors que si tu stockes l'int dans la cellule de liste, cette cellule est déjà dans le cache).
Ca je suis d'accord, mais en général dans une structure on déplace, on ne fait pas vraiment de copie. Si tu veux gérer le cas de la délétion de la structure, 1/ avec des void* le problème se pose aussi, 2/ tu peux donner une fonction "destructeur" au moment de détruire la structure (ou avant), qui se chargera (ou pas) de désallouer ce qu'il faut. Ce problème est inhérent aux langages à gestion manuelle de la mémoire, pas aux templates...
The cake is a lie.