38 votes

Pourquoi l'implémentation et la déclaration d'une classe de modèle devraient-elles être dans le même fichier d'en-tête?

Pourquoi l'implémentation et la déclaration d'une classe de modèle devraient-elles être dans le même fichier d'en-tête? L'un d'entre vous pourrait-il l'expliquer par l'exemple?

25voto

Prasoon Saurav Points 47488

Le compilateur a besoin d'avoir accès à l'ensemble de définition de modèle (et pas seulement de la signature) afin de générer du code pour chaque instanciation du modèle, de sorte que vous devez déplacer les définitions des fonctions de votre en-tête.

Pour plus de détails, lisez au sujet de L'Inclusion du Modèle.

6voto

Anthony Williams Points 28904

La définition d'un modèle de classe et de la mise en œuvre de ses fonctions de membre doit être visible à chaque lieu qui instancie avec un type distinct. c'est à dire pour pouvoir instancier myTemplate<int> vous avez besoin de voir l'intégralité de la définition et de la mise en œuvre de l' myTemplate.

La meilleure façon de le faire est de mettre la définition du modèle et de ses fonctions de membre dans le même en-tête, mais il y a d'autres façons. Par exemple, vous pouvez mettre le membre implémentations de fonction dans un fichier séparé qui a été inclus séparément. Vous pouvez ensuite inclure à partir de la première en-tête, ou seulement inclure la mise en œuvre de fichier là où vous en avez besoin.

Par exemple, une pratique consiste à instancier explicitement un modèle pour l'ensemble particulier de paramètres dans un .fichier cpp et déclarer ces instanciations extern dans l'en-tête. De cette façon, ces instanciations peut être utilisé dans d'autres fichiers source sans nécessiter la mise en œuvre du modèle des fonctions de membre pour être visible. Toutefois, sauf si vous incluez le fichier d'implémentation, vous ne serez pas en mesure d'utiliser d'autres ensembles de paramètres du modèle.

c'est à dire si vous avez myTemplate<int> et myTemplate<std::string> défini comme extern ensuite vous pouvez les utiliser très bien, mais si myTemplate<double> n'est pas définie en extern alors vous ne pouvez pas l'utiliser sans la mise en œuvre.

4voto

liaK Points 6045

Dans le cas d'une classe normale, la déclaration est juste suffisante pour la compilation et les définitions correspondantes seront liées .

Dans le cas des modèles, le compilateur a également besoin de la définition pour générer le code.

La différence est mieux expliquée dans la FAQ C ++ .

4voto

Matthieu M. Points 101624

Ils n'ont pas à.

Ce qui est nécessaire pour la définition de modèle afin d'être visible au moment de l'instanciation (où il est utilisé) pour que le compilateur puisse dériver de la classe de fonction à partir du modèle à ce point.

Cependant, il est très courant d'utiliser deux fichiers d'en-tête pour les classes de modèle:

// foo_fwd.hpp
template <typename T, typename U> struct Foo;

// foo.hpp
#include "foo_fwd.hpp"

template <typename T, typename U> struct Foo { typedef std::pair<T,U> type; };

Cela permet à ceux qui n'ont pas besoin de la pleine définition de modèle pour inclure un peu plus légère en-tête, par exemple:

//is_foo.hpp
#include <boost/mpl/bool.hpp>
#include "foo_fwd.hpp"

template <typename Z>
struct is_foo: boost::mpl::false_ {};

template <typename T, typename U>
struct is_foo< Foo<T,U> >: boost::mpl::true_ {};

ce qui peut accélérer la compilation en temps un peu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X