web-dev-qa-db-fra.com

Utilisation d'un mot-clé d'exportation avec des modèles

Si je comprends bien, le mot-clé "export" peut être utilisé pour que l'on puisse exposer des classes de modèle ou des signatures de fonction à travers un fichier d'en-tête et résumer l'implémentation réelle dans un fichier de bibliothèque.
Quelqu'un peut-il fournir un exemple de programme pratique qui montre comment procéder?
Y a-t-il des inconvénients ou des points importants à noter lors de l'utilisation?

EDIT: Une question de suivi basée sur les réponses. Comme mentionné dans les réponses, "l'exportation" est déconseillée en C++ 0x et rarement prise en charge par les compilateurs, même pour C++ 03x. Compte tenu de cette situation, de quelle manière peut-on masquer des implémentations réelles dans des fichiers lib et simplement exposer des déclarations via des fichiers d'en-tête, afin que l'utilisateur final puisse savoir quelles sont les signatures de l'API exposée sans avoir accès au code source implémentant la même chose?

34
Alok Save

Tout d'abord: la plupart des compilateurs (y compris gcc, Clang et Visual Studio) ne prennent pas en charge le mot clé export.

Il a été implémenté dans un seul front-end: le front-end EDG, et donc seuls les compilateurs qui l'utilisent (Comeau et icc) prennent en charge cette fonctionnalité. Les retours des implémenteurs d'EDG étaient extrêmement simples: cela nous a pris du temps, était extrêmement compliqué, nous vous recommandons de ne pas l'implémenter (1), par conséquent, il a été abandonné en C++ 0x.

Maintenant, la norme permet (et cela est implémenté par au moins gcc):

  • déclarer une version spécialisée d'une fonction de modèle dans un en-tête
  • définir cette spécialisation dans un seul fichier source

et de le faire se comporter comme vous vous attendez d'une fonction régulière.

Remarque: comme le souligne Johannes dans un commentaire, si une spécialisation complète d'une fonction est définie dans un en-tête, elle doit être marquée en ligne sinon le lieur se plaindra.

MODIFIER:

(1) J'ai finalement trouvé ma référence Pourquoi ne pouvons-nous pas nous permettre l'exportation (PDF) par Tom Plum, révisé par Steve Adamczyk, John Spicer et Daveed Vandevoorde d'Edison Design Group qui l'a initialement mis en œuvre dans l'EDG l'extrémité avant.

44
Matthieu M.
12
ltc

Il est difficile de fournir un exemple de programme car presque aucun compilateur ne prend en charge l'exportation. g ++ signalera un avertissement indiquant qu'il n'est pas pris en charge, et IIRC qu'il ne compile même pas dans Visual Studio. De plus, l'exportation est déconseillée en C++ 0x, ce qui signifie qu'il est peu probable que les futurs compilateurs la prennent en charge.

Pour une discussion sur la façon d'utiliser l'exportation dans les quelques compilations qui le supportent (à savoir Comeau C++), consultez ce lien qui explique également pourquoi l'exportation est difficile à implémenter.

Et je vous prie de m'excuser si cela se présente comme un coup de gueule anti-exportation majeur. Je promets de ne pas détester l'exportation! Il n'est tout simplement pas largement pris en charge et vous ne pouvez pas vraiment vous y fier en tant que programmeur.

5
templatetypedef

La raison pour laquelle de nombreux fournisseurs de compilateurs ne l'ont pas pris en charge est que même lorsqu'il fonctionne, il ne le fait pas de la manière attendue par les programmeurs.

Le meilleur article que j'ai trouvé sur les problèmes est ici:

http://msmvps.com/blogs/vandooren/archive/2008/09/24/c-keyword-of-the-day-export.aspx

Il vaut mieux instancier vos modèles.

1
CashCow

J'ai lu un article avec le titre quelque chose comme Export n'est pas pris en charge et il ne ferait pas ce que vous voulez de toute façon.

La seule façon de faire ce que vous voulez est de vous spécialiser complètement, comme cela a été dit. Mais plus que cela, si vous ne pouvez pas voir le code source d'une bibliothèque, vous ne pouvez pas le compiler. Cela signifie que vous ne pouvez pas en accepter la mémoire dynamique car il n'y a aucune garantie que vous utiliserez la suppression correspondante pour leur nouvelle. Par exemple, si mon code est débogué et que la bibliothèque est publiée, le suppresseur ne correspondra pas au nouveau. Vous pouvez utiliser shared_ptr et fournir un deleter, mais c'est TR1 et n'a pas d'export.

0
Tavison