les Templates en C++Edit

article Principal: Modèle (C++)

C++ utilise des modèles pour permettre générique les techniques de programmation. La bibliothèque standard C++ comprend la bibliothèque de modèles Standard ou STL qui fournit un cadre de modèles pour les structures de données et les algorithmes communs. Les modèles en C++ peuvent également être utilisés pour la métaprogrammation de modèles, qui est un moyen de pré-évaluer une partie du code au moment de la compilation plutôt que de l’exécution. En utilisant la spécialisation des modèles, les modèles C++ sont considérés comme Turing complete.,

Techniques de overviewEdit

Il existe deux types de modèles: les modèles de fonction et de modèles de classe. Un modèle de fonction est un modèle pour créer des fonctions ordinaires basées sur les types de paramétrage fournis lors de l’instanciation. Par exemple, la bibliothèque de modèles standard C++ contient le modèle de fonction max(x, y) qui crée des fonctions qui renvoient x ou y, selon le plus grand., max() peut être défini comme ceci:

template <typename T>T max(T x, T y) { return x < y ? y : x;}

les Spécialisations de ce modèle de fonction, les instanciations avec des types spécifiques, peut être appelée comme une fonction ordinaire:

std::cout << max(3, 7); // Outputs 7.

Le compilateur examine les arguments utilisés à l’appel de max et détermine qu’il s’agit d’un appel à max(int, int)., Il instancie ensuite une version de la fonction où le type de paramétrage T est int, faisant l’équivalent de la fonction suivante:

int max(int x, int y) { return x < y ? y : x;}

cela fonctionne si les arguments x et y sont des entiers, des chaînes ou tout autre type pour lequel l’expression x < y est sensible, l’opérateur< est défini. Héritage commun n’est pas nécessaire pour l’ensemble des types qui peuvent être utilisés, et il est donc très similaire à duck-typing., Un programme définissant un type de données personnalisé peut utiliser la surcharge de l’opérateur pour définir la signification de < pour ce type, permettant ainsi son utilisation avec le modèle de fonction max (). Tandis que ceci peut sembler un léger avantage dans cet exemple isolé, dans le contexte d’une bibliothèque complète comme la STL, il permet au programmeur d’obtenir de nombreuses fonctionnalités pour un nouveau type de données, tout en définissant quelques opérateurs., La simple définition de < permet d’utiliser un type avec les algorithmes standard sort(), stable_sort () et binary_search() ou de le placer dans des structures de données telles que des ensembles, des tas et des tableaux associatifs.

Les modèles C++ sont complètement sûrs au moment de la compilation. En démonstration, le complexe de type standard ne définit pas l’opérateur <, car il n’y a pas d’ordre strict sur les nombres complexes. Par conséquent, max(x, y) échoue avec une erreur de compilation, si x et y sont des valeurs complexes., De même, d’autres modèles qui reposent sur < ne peuvent pas être appliqués à des données complexes à moins qu’une comparaison (sous la forme d’un foncteur ou d’une fonction) ne soit fournie. Par exemple: un complexe ne peut pas être utilisé comme clé pour une carte à moins qu’une comparaison ne soit fournie. Malheureusement, les compilateurs génèrent historiquement des messages d’erreur quelque peu ésotériques, longs et inutiles pour ce type d’erreur. S’assurer qu’un certain objet adhère à un protocole de méthode peut atténuer ce problème. Les langages qui utilisent compare au lieu de < peuvent également utiliser des valeurs complexes comme clés.,

le deuxième type de modèle, un modèle de classe, étend le même concept aux classes. Une spécialisation de modèle de classe est une classe. Les modèles de classe sont souvent utilisés pour créer des conteneurs génériques. Par exemple, le STL a un conteneur de liste chaînée. Pour faire une liste chaînée d’entiers, on écrit la liste des<int>. Une liste de chaînes de caractères est indiquée la liste des<string>. Une liste a un ensemble de fonctions standard qui lui sont associées, qui fonctionnent pour tous les types de paramétrage compatibles.,

Template specializationEdit

Une fonctionnalité puissante des templates de C++est la spécialisation des templates. Cela permet de fournir des implémentations alternatives en fonction de certaines caractéristiques du type paramétré en cours d’instanciation. La spécialisation des modèles a deux objectifs: permettre certaines formes d’optimisation et réduire le gonflement du code.

par exemple, considérons une fonction de modèle sort (). L’une des principales activités d’une telle fonction est d’échanger ou d’échanger les valeurs dans deux des positions du conteneur., Si les valeurs sont grandes (en termes de nombre d’octets nécessaires pour stocker chacune d’elles), il est souvent plus rapide de créer d’abord une liste distincte de pointeurs vers les objets, de trier ces pointeurs, puis de créer la séquence triée finale. Si les valeurs sont assez petites, il est généralement plus rapide de simplement échanger les valeurs sur place au besoin. De plus, si le type paramétré est déjà de type pointeur, il n’est pas nécessaire de créer un tableau de pointeur séparé., La spécialisation de modèle permet au créateur de modèle d’écrire différentes implémentations et de spécifier les caractéristiques que le(s) type (S) paramétré (s) doit avoir pour chaque implémentation à utiliser.

Contrairement aux modèles de fonction, les modèles de classe peuvent être partiellement spécialisés. Cela signifie qu’une version alternative du code de modèle de classe peut être fournie lorsque certains paramètres de modèle sont connus, tout en laissant d’autres paramètres de modèle génériques., Cela peut être utilisé, par exemple, pour créer une implémentation par défaut (la spécialisation principale) qui suppose que la copie d’un type de paramétrage est coûteuse, puis créer des spécialisations partielles pour les types peu coûteux à copier, augmentant ainsi l’efficacité globale. Les Clients d’un tel modèle de classe utilisent simplement des spécialisations sans avoir besoin de savoir si le compilateur a utilisé la spécialisation principale ou une spécialisation partielle dans chaque cas., Les modèles de classe peuvent également être entièrement spécialisés, ce qui signifie qu’une implémentation alternative peut être fournie lorsque tous les types de paramétrage sont connus.

avantages et désavantagesedit

certaines utilisations de templates, telles que la fonction max (), étaient auparavant remplies par des macros de préprocesseur de type Fonction (Un héritage du langage de programmation C). Par exemple, voici une macro max() possible:

#define max(a,b) ((a) < (b) ? (b) : (a))

Les Macros sont développées par le préprocesseur, avant la compilation proprement dite; les modèles sont développés au moment de la compilation., Les Macros sont toujours développées en ligne; les modèles peuvent également être développés en tant que fonctions en ligne lorsque le compilateur le juge approprié. Ainsi, les macros de type Fonction et les modèles de fonction n’ont pas de surcharge d’exécution.

cependant, les modèles sont généralement considérés comme une amélioration par rapport aux macros à ces fins. Les modèles sont sûrs de type. Les modèles évitent certaines des erreurs courantes trouvées dans le code qui fait un usage intensif des macros de type Fonction, telles que l’évaluation des paramètres avec des effets secondaires deux fois. Peut-être le plus important, les modèles ont été conçus pour être applicables à des problèmes beaucoup plus importants que les macros.,

Il y a quatre principaux inconvénients à l’utilisation des modèles: les fonctionnalités prises en charge, la prise en charge du compilateur, les messages d’erreur médiocres et le gonflement du code:

  1. Les modèles en C++ manquent de nombreuses fonctionnalités, ce qui rend leur implémentation et leur utilisation simple souvent impossible. Au lieu de cela, les programmeurs doivent compter sur des astuces compliquées qui conduisent à un code gonflé, difficile à comprendre et difficile à maintenir. Les développements actuels dans les normes C++ exacerbent ce problème en faisant un usage intensif de ces astuces et en construisant beaucoup de nouvelles fonctionnalités pour les modèles sur eux ou avec eux à l’esprit.,
  2. de nombreux compilateurs ont historiquement une mauvaise prise en charge des modèles, donc l’utilisation de modèles peut rendre le code un peu moins portable. La prise en charge peut également être médiocre lorsqu’un compilateur C++ est utilisé avec un éditeur de liens qui n’est pas compatible avec C++, ou lorsque vous essayez d’utiliser des modèles à travers les limites de bibliothèques partagées. Cependant, la plupart des compilateurs modernes ont maintenant un support de modèle assez robuste et standard, et la nouvelle norme C++, C++11, répond davantage à ces problèmes.
  3. presque tous les compilateurs produisent des messages d’erreur déroutants, longs ou parfois inutiles lorsque des erreurs sont détectées dans du code utilisant des modèles., Cela peut rendre les modèles difficiles à développer.
  4. enfin, l’utilisation de templates nécessite que le compilateur génère une instance distincte de la classe ou de la fonction templated pour chaque permutation des paramètres de type utilisés avec elle. (Cela est nécessaire car les types en C++ ne sont pas tous de la même taille et les tailles des champs de données sont importantes pour le fonctionnement des classes.) Ainsi, l’utilisation aveugle de modèles peut entraîner un gonflement du code, entraînant des exécutables excessivement volumineux., Cependant, une utilisation judicieuse de la spécialisation et de la dérivation des modèles peut réduire considérablement ce gonflement du code dans certains cas:

alors, la dérivation peut-elle être utilisée pour réduire le problème du code répliqué parce que les modèles sont utilisés? Cela impliquerait de dériver un modèle à partir d’une classe ordinaire. Cette technique s’est avérée efficace pour limiter le gonflement du code en utilisation réelle. Les personnes qui n’utilisent pas une technique comme celle-ci ont constaté que le code répliqué peut coûter des mégaoctets d’espace de code, même dans les programmes de taille modérée.,

— Bjarne Stroustrup, the Design and Evolution of C++, 1994

les instanciations supplémentaires générées par les templates peuvent également causer des difficultés aux débogueurs à travailler correctement avec les templates. Par exemple, la définition d’un point d’arrêt de débogage dans un modèle à partir d’un fichier source peut soit ne pas définir le point d’arrêt dans l’instanciation réelle souhaitée, soit définir un point d’arrêt à chaque endroit où le modèle est instancié.,

de plus, comme le compilateur doit effectuer des extensions de modèles de type macro et en générer différentes instances au moment de la compilation, le code source d’implémentation de la classe ou de la fonction modélisée doit être disponible (par exemple inclus dans un en-tête) pour le code qui l’utilise. Les classes ou fonctions modélisées, y compris une grande partie de la bibliothèque de modèles Standard (STL), si elles ne sont pas incluses dans les fichiers d’en-tête, ne peuvent pas être compilées. (Cela contraste avec le code non Templé, qui peut être compilé en binaire, ne fournissant qu’un fichier d’en-tête de déclarations pour le code qui l’utilise.,) Cela peut être un inconvénient en exposant le code d’implémentation, ce qui supprime certaines abstractions, et pourrait restreindre son utilisation dans les projets à source fermée.

Templates dans DEdit

le langage de programmation d prend en charge les modèles basés sur la conception C++.,La plupart des idiomes de modèle C++ seront reportés à D sans modification, mais D ajoute des fonctionnalités supplémentaires:

  • Les paramètres de modèle dans D ne sont pas limités aux seuls types et valeurs primitives, mais autorisent également des valeurs de compilation arbitraires (telles que des chaînes et des littéraux de structure), et des alias à des identifiants arbitraires, y
  • Les contraintes de Template et l’instruction static if fournissent une alternative au mécanisme de substitution de C++failure is not an error (SFINAE), similaire aux concepts C++.
  • Le est(…,) expression permet l’instanciation spéculative pour vérifier les traits d’un objet au moment de la compilation.
  • Le mot-clé auto et l’expression typeof permettent l’inférence de type pour les déclarations de variables et les valeurs de retour de fonction, ce qui permet à son tour les « types Voldemort » (types qui n’ont pas de nom global).

Les Templates en D utilisent une syntaxe différente de celle en C++: alors qu’en C++ les paramètres de template sont placés entre crochets angulaires (Template<param1, param2>),D utilise un signe d’exclamation et des parenthèses: Template!(param1, param2).,Cela évite les difficultés D’analyse C++ dues à l’ambiguïté avec les opérateurs de comparaison.S’il n’y a qu’un seul paramètre, les parenthèses peuvent être omises.

classiquement, D combine les caractéristiques ci-dessus pour fournir un polymorphisme au moment de la compilation en utilisant une programmation générique basée sur des traits.,Par exemple, une plage d’entrée est définie comme n’importe quel type qui satisfait aux vérifications effectuées par isInputRange, qui est défini comme suit:

Une fonction qui n’accepte que des plages d’entrée peut alors utiliser le modèle ci-dessus dans une contrainte de modèle:

auto fun(Range)(Range range) if (isInputRange!Range){ // ...}
code generationEdit

en plus de la métaprogrammation de modèle, D fournit également plusieurs fonctionnalités pour-génération de code temporel:

  • l’expression import permet de lire un fichier à partir du disque et d’utiliser son contenu comme expression de chaîne.,
  • La réflexion au moment de la compilation permet d’énumérer et d’inspecter les déclarations et leurs membres lors de la compilation.
  • les attributs définis par L’utilisateur permettent aux utilisateurs d’attacher des identifiants arbitraires aux déclarations, qui peuvent ensuite être énumérées en utilisant la réflexion au moment de la compilation.
  • L’exécution de la fonction au moment de la compilation (CTFE) permet d’interpréter un sous-ensemble de D (limité aux opérations sûres) pendant la compilation.
  • les mixins de chaîne permettent d’évaluer et de compiler le contenu d’une expression de chaîne sous forme de code D qui devient une partie du programme.,

La combinaison de ce qui précède permet de générer du code basé sur des déclarations existantes.Par exemple, les frameworks de sérialisation D peuvent énumérer les membres d’un type et générer des fonctions spécialisées pour chaque type sérialisé pour effectuer la sérialisation et la désérialisation.Les attributs définis par l’utilisateur pourraient indiquer davantage les règles de sérialisation.

l’expression d’importation et l’exécution de la fonction de compilation permettent également d’implémenter efficacement des langages spécifiques au domaine.,Par exemple, étant donné une fonction qui prend une chaîne contenant un modèle HTML et renvoie un code source d équivalent, il est possible de l’utiliser de la manière suivante:

Genericity in EiffelEdit

Les classes génériques font partie D’Eiffel depuis la conception originale de la méthode et du langage. Les publications de la fondation Eiffel, utilisent le terme généricité pour décrire la création et l’utilisation de classes génériques.

basic/Unconstrained genericityEdit

Les classes génériques sont déclarées avec leur nom de classe et une liste d’un ou plusieurs paramètres génériques formels., Dans le code suivant, class LIST a un paramètre générique formel G

Les paramètres génériques formels sont des espaces réservés pour les noms de classe arbitraires qui seront fournis lorsqu’une déclaration de la classe générique est faite, comme indiqué dans les deux dérivations génériques ci-dessous, où ACCOUNT« d40ace6f03 »> sont d’autres noms de classe. ACCOUNT et DEPOSIT sont considérées comme de véritables paramètres génériques car ils fournissent des vrais noms de classe à remplacer G en utilisation réelle.,

 list_of_accounts: LIST -- Account list list_of_deposits: LIST -- Deposit list

dans le système de type Eiffel, bien que la classe LIST soit considérée comme une classe, elle n’est pas considérée comme un type. Cependant, une dérivation générique de LIST telle que LIST est considérée comme un type.

Contraint genericityEdit

Pour la liste de classe indiqué ci-dessus, un paramètre générique de substitution G peut être n’importe quelle autre classe., Pour contraindre l’ensemble des classes à partir desquelles des paramètres génériques réels valides peuvent être choisis, une contrainte générique peut être spécifiée. Dans la déclaration de class SORTED_LIST ci-dessous, la contrainte Générique dicte que tout paramètre générique réel valide sera une classe qui hérite de class COMPARABLE. La contrainte Générique garantit que les éléments d’un SORTED_LIST peuvent en fait être triés.,

class SORTED_LIST 

Generics in JavaEdit

Main article: Generics in Java

La prise en charge des génériques, ou « containers-of-type-t », a été ajoutée au langage de programmation Java en 2004 dans le cadre de J2SE 5.0. En Java, les génériques ne sont vérifiés qu’au moment de la compilation pour l’exactitude du type. Les informations de type générique sont ensuite supprimées via un processus appelé Type erasure, pour maintenir la compatibilité avec les anciennes implémentations JVM, ce qui les rend indisponibles lors de l’exécution., Par exemple, une liste<chaîne> est convertie en liste de types bruts. Le compilateur insère des moulages de type pour convertir les éléments en type chaîne lorsqu’ils sont récupérés dans la liste, réduisant ainsi les performances par rapport à d’autres implémentations telles que les modèles C++.

généricité dans.NET Edit

Les génériques ont été ajoutés dans le cadre de. NET Framework 2.0 en novembre 2005, sur la base d’un prototype de recherche de Microsoft Research lancé en 1999. Bien que similaire aux génériques en Java, .,Les génériques NET n’appliquent pas l’effacement de type, mais implémentent les génériques en tant que mécanisme de première classe dans l’exécution à l’aide de la réification. Ce choix de conception fournit des fonctionnalités supplémentaires, telles que permettre la réflexion avec la préservation des types génériques, ainsi que d’atténuer certaines des limitations de l’effacement (comme l’impossibilité de créer des tableaux génériques). Cela signifie également qu’il n’y a pas de coup de performance des lancers d’exécution et des conversions de boxe normalement coûteuses., Lorsque les types primitifs et value sont utilisés comme arguments génériques, ils obtiennent des implémentations spécialisées, permettant des collections et des méthodes génériques efficaces. Comme en C++ et Java, les types génériques imbriqués tels que Dictionary<string, List<int>> sont des types valides, mais sont déconseillés pour les signatures de membres dans les règles de conception d’analyse de code.

.,NET autorise six variétés de contraintes de type génériques utilisant le mot clé where, y compris la restriction des types génériques pour qu’ils soient des types de valeur, des classes, des constructeurs et des interfaces. Voici un exemple avec une contrainte d’interface:

la méthode MakeAtLeast() permet l’opération sur des tableaux, avec des éléments de type générique T. la contrainte de type de la méthode indique que la méthode est applicable à tout type T qui implémente L’IComparable Générique<T> interface., Cela garantit une erreur de compilation, si la méthode est appelée si le type ne prend pas en charge la comparaison. L’interface fournit la méthode générique CompareTo (T).

la méthode ci-dessus pourrait également être écrite sans types génériques, en utilisant simplement le type de tableau non générique. Cependant, puisque les tableaux sont contravariants, le casting ne serait pas sûr de type et le compilateur serait incapable de trouver certaines erreurs possibles qui seraient autrement interceptées lors de l’utilisation de types génériques. De plus, la méthode aurait besoin d’accéder aux éléments du tableau en tant qu’objets à la place, et nécessiterait une conversion pour comparer deux éléments., (Pour les types de valeur comme les types tels que int, cela nécessite une conversion de boxe, bien que cela puisse être contourné en utilisant la classe Comparer <T>, comme cela se fait dans les classes de collection standard.)

un comportement notable des membres statiques dans une classe.Net Générique est l’instanciation des membres statiques par type d’exécution (voir l’exemple ci-dessous).

Genericity in DelphiEdit

le dialecte Object Pascal de Delphi a acquis des génériques dans la version Delphi 2007, initialement uniquement avec le (maintenant abandonné) .,Compilateur NET avant d’être ajouté au code natif dans la version Delphi 2009. La sémantique et les capacités des génériques Delphi sont largement calquées sur celles des génériques dans.net 2.0, bien que l’implémentation soit nécessairement très différente. Voici une traduction plus ou moins directe du premier exemple c# montré ci-dessus:

comme avec C#, Les méthodes ainsi que les types entiers peuvent avoir un ou plusieurs paramètres de type. Dans l’exemple, TArray est un type générique (défini par le langage) et MakeAtLeast une méthode générique., Les contraintes disponibles sont très similaires aux contraintes disponibles en C#: tout type de valeur, toute classe, une classe ou une interface spécifique et une classe avec un constructeur sans paramètre. Les contraintes multiples agissent comme une union additive.

généricité dans Free PascalEdit

Free Pascal a implémenté des génériques avant Delphi, et avec une syntaxe et une sémantique différentes. Cependant, depuis la version 2.6.0 de FPC, la syntaxe de style Delphi est disponible lors de l’utilisation du mode de langage {mode Mode Delphi}. Ainsi, les programmeurs Free Pascal sont capables d’utiliser des génériques dans le style qu’ils préfèrent.,

Delphi et Free Pascal exemple:

functional languagesEdit

Genericity in HaskellEdit

le mécanisme de classe de type de Haskell prend en charge la programmation générique.Six des classes de types prédéfinies dans Haskell (y compris Eq, les types qui peuvent être comparés pour l’égalité, et Show, les types dont les valeurs peuvent être rendues sous forme de chaînes) ont la propriété spéciale de prendre en charge les instances dérivées., Cela signifie qu’un programmeur définissant un nouveau type peut indiquer que ce type doit être une instance de l’une de ces classes de type spécial, sans fournir d’implémentations des méthodes de classe comme cela est généralement nécessaire lors de la déclaration d’instances de classe. Toutes les méthodes nécessaires seront « dérivées » – c’est-à-dire construites automatiquement-en fonction de la structure du type.,Par exemple, la déclaration suivante d’un type d’arbres binaires indique qu’il doit être une instance des classes Eq et Show:

data BinTree a = Leaf a | Node (BinTree a) a (BinTree a) deriving (Eq, Show)

Il en résulte qu’une fonction d’égalité (==) et une fonction de représentation de chaîne (show) sont automatiquement définies pour tout type de la forme BinTree T à condition que t,

Le support des instances dérivées de Eq et Show rend leurs méthodes == et show génériques d’une manière qualitativement différente des fonctions polymorphes para-métriques: ces « fonctions » (plus précisément, les familles de fonctions indexées par type) peuvent être appliquées à des valeurs de différents types, et bien qu’elles se comportent différemment pour chaque type d’argument, peu de travail est nécessaire Ralf Hinze (2004) a montré qu’un effet similaire peut être obtenu pour les classes de type définies par l’utilisateur par certaines techniques de programmation., D’autres chercheurs ont proposé des approches à ce sujet et à d’autres types de généricité dans le contexte de Haskell et des extensions de Haskell (discutées ci-dessous).

PolyPEdit

PolyP a été la première extension de langage de programmation générique à Haskell. Dans polype, les fonctions génériques sont appelées polytypiques. Le langage introduit une construction spéciale dans laquelle de telles fonctions polytypiques peuvent être définies par induction structurelle sur la structure du foncteur de motif d’un type de données régulier. Les types de données réguliers dans polype sont un sous-ensemble de types de données Haskell., Un type de données régulier T doit être de type*→*, et si a est l’argument de type formel dans la définition, alors tous les appels récursifs à t doivent avoir la forme T A. ces restrictions excluent les types de données de type supérieur ainsi que les types de données imbriqués, où les appels récursifs sont d’une forme différente. La fonction aplatir dans polype est ici fournie à titre d’exemple:

Generic Haskelldit

Generic Haskell est une autre extension de Haskell, développée à L’Université D’Utrecht aux Pays-Bas., Les extensions qu’il fournit sont:

  • Les valeurs indexées par Type sont définies comme une valeur indexée sur les différents constructeurs de type Haskell (unité, types primitifs, sommes, produits et constructeurs de type définis par l’utilisateur). En outre, nous pouvons également spécifier le comportement d’une valeur indexée par type pour un constructeur spécifique en utilisant des cas de constructeur, et réutiliser une définition générique dans une autre en utilisant des cas par défaut.

la valeur type-indexée résultante peut être spécialisée à n’importe quel type.

  • Les types indexés sont des types indexés sur des types, définis en donnant un cas pour * et k → k’., Les Instances sont obtenues en appliquant le type indexé kind à un type.
  • Les définitions génériques peuvent être utilisées en les appliquant à un type ou un type. C’est ce qu’on appelle une application générique. Le résultat est un type ou une valeur, selon le type de définition générique appliqué.
  • l’abstraction générique permet de définir des définitions génériques en abstrayant un paramètre de type (d’un type donné).
  • Les types indexés sont des types qui sont indexés sur les constructeurs de types. Ceux-ci peuvent être utilisés pour donner des types à des valeurs génériques plus impliquées., Les types indexés par type résultants peuvent être spécialisés à n’importe quel type.

à titre d’exemple, la fonction d’égalité dans le Haskell Générique:

CleanEdit

Clean offre un polype Générique basé sur la programmation et le Haskell Générique pris en charge par le GHC>=6.0. Il paramétrise par type comme ceux-ci mais offre une surcharge.

autres languesmodifier

la famille de langages de programmation ML prend en charge la programmation générique à travers le polymorphisme paramétrique et les modules génériques appelés foncteurs.,ML Standard et OCaml fournissent des foncteurs, qui sont similaires aux modèles de classes et aux paquets génériques D’Ada. Les abstractions syntaxiques de Scheme ont également un lien avec la généricité – ce sont en fait un sur-Ensemble de modèles à la c++.

un module Verilog peut prendre un ou plusieurs paramètres, auxquels leurs valeurs réelles sont affectées lors de l’instanciation du module. Un exemple est un tableau de registre générique où la largeur du tableau est donnée via un paramètre., Un tel réseau, combiné avec un vecteur fil générique, peut créer un tampon générique ou un module de mémoire avec une largeur de bit arbitraire à partir d’une seule implémentation de module.

VHDL, étant dérivé D’Ada, a également des capacités génériques.