Quels sont les inconvénients de l'utilisation de modèles?
Quelques-uns des inconvénients serait
- sa syntaxe est complexe
- compilateur génère un code supplémentaire
compilateur génère un code supplémentaire, j'ai lu quelque part (mr. Stroustrup, je pense) que sur les compilateurs modernes en fait pas - pas une seule instruction de frais généraux
Je n'ai pas par la "syntaxe complexe" argument. Si vous trouvez la syntaxe du modèle de la confusion, on devrait être en mettant l'accent sur la nécessité de continuer à apprendre la langue, à ne pas prendre à elle. Et 2 devraient être largement hors de propos, IIRC.
Je pense que le code supplémentaire se produit par exemple lorsque vous instanciez votre basé sur un modèle de récipient à l'encontre de N différents types, et le compilateur génère N légèrement différentes versions du code conteneur. (Comparez cela à la méthode classique où vous avez à la main le code une seule classe de conteneur qui peut contenir n'importe quel type d'objet... dangereux au moment de l'exécution, mais seulement une copie de l'contenant le code est généré)
Si votre compilateur ne peut pas plier dupliquer à l'identique le code généré à partir de modèles, il y a des techniques pour - en toute sécurité! - le faire dans le code (comme fondant tous
et de Dames: Vous n'avez pas besoin d'inclure la totalité des alias pour les notifications (et vous ne pouvez pas me prévenir 😉, voir blog.stackoverflow.com/2010/01/new-improved-comments-with-reply
Je n'ai pas par la "syntaxe complexe" argument. Si vous trouvez la syntaxe du modèle de la confusion, on devrait être en mettant l'accent sur la nécessité de continuer à apprendre la langue, à ne pas prendre à elle. Et 2 devraient être largement hors de propos, IIRC.
Je pense que le code supplémentaire se produit par exemple lorsque vous instanciez votre basé sur un modèle de récipient à l'encontre de N différents types, et le compilateur génère N légèrement différentes versions du code conteneur. (Comparez cela à la méthode classique où vous avez à la main le code une seule classe de conteneur qui peut contenir n'importe quel type d'objet... dangereux au moment de l'exécution, mais seulement une copie de l'contenant le code est généré)
Si votre compilateur ne peut pas plier dupliquer à l'identique le code généré à partir de modèles, il y a des techniques pour - en toute sécurité! - le faire dans le code (comme fondant tous
T*
instances sur un void*
avec un mince au moment de la compilation emballage autour de lui pour le type de sécurité).et de Dames: Vous n'avez pas besoin d'inclure la totalité des alias pour les notifications (et vous ne pouvez pas me prévenir 😉, voir blog.stackoverflow.com/2010/01/new-improved-comments-with-reply
OriginalL'auteur anish | 2010-04-29
Vous devez vous connecter pour publier un commentaire.
Ils sont difficiles à valider. Modèle de code qui n'est pas habitué a tendance à être rarement compilé à tous. Par conséquent, une bonne couverture de cas de test est un must. Mais les essais de temps, et puis il se peut que le code n'aurait jamais dû être robuste en premier lieu.
Un autre problème peut être que les modèles peuvent être utilisés pour prévenir code à partir de la compilation: par exemple, s'assurer qu'un modèle de classe n'est jamais instanciée avec certains paramètres du modèle. Il est généralement difficile d'écrire des tests de vérifier que le code ne compile pas. 🙂
C'est bon, c'est dur pour s'assurer que tous les modèle de méthodes fonctionnent correctement avec une variété de types de données lorsque vous ne pouvez pas besoin de l'interface complète au départ.
OriginalL'auteur Potatoswatter
Hmm, comment au sujet de...
3: Ils peuvent être lent à compiler
4: Ils ont la force des choses être calculé au moment de la compilation plutôt que de courir de temps (cela peut aussi être un avantage, si vous préférez rapide la vitesse d'exécution en cours d'exécution de la souplesse)
5: les Anciens compilateurs C++ ne pas les manipuler, ou de ne pas les gérer correctement
6: Les messages d'erreur qu'elles génèrent lorsque vous n'obtenez pas le bon code peut être à peu près incompréhensible
Eh bien, il a demandé à tous les inconvénients, non seulement insurmontable inconvénients 🙂
Je suis en désaccord avec votre POV re #6. Pour l'innocent, à la recherche
std::list<int> l; std::sort(l.begin(),l.end());
VC9 crache de 7,5 kB message d'erreur à vous, à tous point de std lib en-têtes. Même si je comprends tout à fait pourquoi le tri d'une liste de cette façon ne fonctionne pas, 7,5 ko de messages d'erreur sont beaucoup trop à comprendre.C'est de 28 messages d'erreur ici, les points de mon code, et qui dit
see reference to function template instantiation 'void std::sort<std::list<_Ty>::_Iterator<_Secure_validation>>(_RanIt,_RanIt)' being compiled
- qui est un très version déformée de ce que j'ai appelé. Vous devriez voir comment les humbles ouvriers approche de mon bureau quand ils courent dans l'une de ces. Et le premier point de vue est toujours dans le code écrit, parce que la compréhension de ce qui s'est passé en regardant votre propre code (pas le message d'erreur qu'il provoque) est habituellement votre meilleur pari. Et c'est tout simplement faux.Je dirais que le principal inconvénient avec les modèles pauvres des messages d'erreur. Ils ne sont pas facilement compréhensible, ce qui est une partie de la raison concepts ont été ajoutés pour C++0x: afin d'améliorer les diagnostics. Je dirais que je comprends des modèles très bien, mais même une erreur aussi simple que d'avoir protégé le destructeur d'une classe stockées dans un
unique_ptr
m'a laissé réfléchir à une page au long de message d'erreur pendant un certain temps. Pas utile. (Oui, je suis stupide pour faire ça 😛 mais les gens des gros doigts choses tout le temps, qui est pourquoi les bons diagnostics sont importants)OriginalL'auteur Jeremy Friesner
Modèles de les exposer à la mise en œuvre aux clients de votre code, ce qui rend le maintien de votre ABI plus difficile si vous passez basé sur un modèle d'objets à la bibliothèque de limites.
OriginalL'auteur Alex B
Le seul vrai inconvénient est que si vous faites toute petite erreur de syntaxe dans un modèle (en particulier celle qui est utilisée par d'autres modèles) les messages d'erreur sont pas va être utile... attendons les pages d'un couple de quasi-inutilisable messages d'erreur;-). Les compilateurs " défaut sont très compilateur spécifique, et la syntaxe, tandis que laid, n'est pas vraiment "complexe". Dans l'ensemble, bien que-en dépit de l'énorme problème avec les bons diagnostics d'erreur -- les modèles sont encore la meilleure chose à propos de C++, la seule chose qui pourrait bien vous donner envie d'utiliser le C++ sur d'autres langues avec des implémentations de génériques, tels que Java...
OriginalL'auteur Alex Martelli
Jusqu'à présent personne ne semble avoir mentionné le principal inconvénient je trouve avec les modèles: la lisibilité du code s'effondre!
Je ne parle pas des problèmes de syntaxe -- oui la syntaxe est moche, mais je peux pardonner. Ce que je veux dire est ceci: j'ai trouver que jamais-vu-avant non basées sur des modèles de code, toutefois, les grandes la demande est, si je commence à
main()
je suis habituellement capable de décoder les grandes lignes de ce programme est de le faire sans problèmes. Et le code qui utilise simplementvector<int>
ou similaire ne me dérange pas le moins du monde. Mais une fois que le code commence à définir et à utiliser ses propres modèles pour les fins-delà de la simple types de conteneurs, d'intelligibilité rapidement va à la fenêtre. Ce qui a des conséquences négatives pour la maintenance du code.Partie de cela est inévitable: les modèles de permettre une plus grande expressivité via le complexe partielle-de l'ordre de résolution de surcharge règles (pour les modèles de fonction) et, à un moindre degré, partielle spécialisation (pour les modèles de classe). Mais les règles sont donc sacrément compliqué que même les rédacteurs du compilateur (qui, je suis heureux de reconnaître comme étant un ordre de grandeur plus intelligent que je suis) sont encore à se tromper en cas de coin.
L'interaction des espaces de noms, des amis, de l'héritage, surcharge, les conversions automatiques et argument-dépendante de recherche en C++ est déjà assez compliqué. Mais lorsque vous ajoutez des modèles dans le mélange, ainsi que les légères modifications des règles pour la recherche d'un nom et conversions automatiques qu'ils viennent avec, la complexité peut atteindre des proportions qui, je dirais, aucun humain ne peut traiter. Je n'ai pas confiance en moi-même à lire et à comprendre un code qui permet l'utilisation de toutes ces constructions.
Une autre difficulté avec les modèles est que les débogueurs ont encore du mal à montrer le contenu de conteneurs STL naturellement (par rapport à, disons, C-style de tableaux).
Merci Ben, oui, c'est TMP qui cause le plus de maux de tête. Et que de bonnes nouvelles à propos de Visual Studio, je dois avoir été invocation de la frustration causée par une version antérieure. Ou est-ce une caractéristique de non-éditions Express?
OriginalL'auteur j_random_hacker
Ils sont complexes pour le compilateur à analyser ce qui signifie que votre temps de compilation va augmenter. Il peut aussi être difficile à analyser les messages d'erreur du compilateur si vous avez avancé modèle de constructions.
OriginalL'auteur Andreas Brinck
Moins les gens comprennent, epsecially au niveau de la méta-programmation, donc moins de gens peuvent les maintenir.
OriginalL'auteur Michael Dorgan
Lorsque vous utilisez des modèles, votre compilateur génère uniquement ce que vous utilisez réellement. Je ne pense pas qu'il y a des inconvénients à l'utilisation de C++ modèle de méta-programmation à l'exception de la compilation de temps qui peut être assez long si vous avez utilisé des structures très complexes comme boost ou loki bibliothèques.
OriginalL'auteur Opera
Un inconvénient: modèle erreurs sont détectées uniquement par le compilateur lorsque le modèle est instancié. Parfois, les erreurs dans les méthodes de modèles sont détectés uniquement lorsque la méthode de membre est instancié, peu importe si le reste du modèle est instancié.
Si j'ai une erreur dans une méthode, d'une classe de modèle, que d'une seule fonction de références, mais d'autres code utilise le modèle sans cette méthode, le compilateur ne génère pas d'erreur jusqu'à ce que l'erreur de méthode est instancié.
OriginalL'auteur Thomas Matthews
L'absolu pire: Les messages d'erreur du compilateur que vous obtenez de mauvais code du modèle.
OriginalL'auteur Earlz
J'ai utilisé des modèles parfois, au fil des ans. Ils peuvent être à portée de main, mais à partir d'un point de vue professionnel, je me penche loin d'eux. Deux raisons sont:
1.
La nécessité d'un.) exposer la définition d'une fonction (pas uniquement des déclarations) "source" code "utilisé" code ou b.) créer un mannequin d'instanciation dans le fichier source. Ceci est nécessaire pour la compilation. Option un.) peut être fait par la définition des fonctions dans l'en-tête ou de fait, y compris le rpc.
L'une des raisons qui nous tolérer les en-têtes en C++ (par rapport à C# par exemple) est à cause de la séparation de "l'interface" de "mise en œuvre". Ainsi, les modèles semblent être en contradiction avec cette philosophie.
2.
Les fonctions appelées par un modèle de type de paramètre d'instanciation peut ne pas être respectées au moment de la compilation, entraînant des erreurs de lien. E. g. T exemple; exemple.CompilerDoesntKnowIfThisFunctionexistsont();
C'est la "loose" à mon humble avis.
Solutions:
Plutôt que modèles, je me penche vers l'utilisation d'une classe de base selon lequel la dérivée/classes conteneur savoir ce qui est disponible au moment de la compilation. Les classes de base peut fournir le générique des méthodes et des "types" que les modèles sont souvent utilisés pour. C'est pourquoi le code source de la disponibilité peuvent être utiles, si existant, le code doit être modifié pour insérer un générique de la classe de base dans la hiérarchie d'héritage en cas de besoin. Dans le cas contraire, le code est à code source fermé, réécrire une meilleure utilisation de générique classes de base au lieu d'utiliser un modèle comme un travail autour de.
Si le type est sans importance, par exemple, vector< T > alors que diriez-vous simplement à l'aide d'un"objet". C++ n'a pas fourni un "objet" mot-clé, et j'ai proposé à M. Bjarne Stroustrup que ce serait utile, surtout pour dire compilateur et les gens de la lecture de code de ce type n'est pas important (pour les cas où il n'est pas). Je ne pense pas que C++11 a cela, peut-être C++14?
OriginalL'auteur Greg McPherran