Bonjour tout le monde,
Je cherche une méthode afin d'exporter une version compilée de mes templates au sein d'une bibliothèque sans pour autant fournir le fichier du template.
Est-ce faisable?
Merci
Bonjour tout le monde,
Je cherche une méthode afin d'exporter une version compilée de mes templates au sein d'une bibliothèque sans pour autant fournir le fichier du template.
Est-ce faisable?
Merci
Une version compilée de templates c++ ? Ça ne fait pas sens pour moi vu que les templates sont utilisés à la compilation
Ou ai-je mal compris la question ?
La liberté est à la sociologie ce que l'instant présent est à la physique relativiste.
Oui, je me suis mal exprimé. En fait, j'ai un template représentant des images. Ces images peuvent être soient de type float soit de type entier par exemple. Je voulais éviter de donner l'implémentation de cette classe template en ne donnant juste leur "spécialisation" (en utilisant typedef par exemple).
Oui si comme j'ai compris, c'est le type de données qui est templatisé, tu dois pouvoir faire un typedef dans un header.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 template<typename T> class mine { public: mine(T v):d(v){} private: T d; }; typedef mine<int> mineint; typedef mine<float> minefloat;
La liberté est à la sociologie ce que l'instant présent est à la physique relativiste.
Tu peux passer par une astuce: la spécialisation de type incomplet:
La classe template n'est pas définie dans le cas général, et est spécialisée pour deux cas précis
L'en-tête contiendrait:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 template <typename T> class Bidule; //surtout pas d'accolades template <> class Bidule<int> { // ce que tu veux }; template <typename T> class Bidule<float> { // ce que tu veux };
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- Une variable de moins est une source d'erreur en moins.
- Un pointeur de moins est une montagne d'erreurs en moins.
- Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
- jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
- La plus sotte des questions est celle qu'on ne pose pas.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
Merci pour vos réponses.
@SkyZoThreaD: le problème avec cette méthode, c'est que j'exporte le template ce que je souhaite.
@leternel: je ne souhaite pas vraiment spécialiser les templates, mais plutôt les définir.
Mon but est d'éviter d'inclure certains en-tête entraînant des dépendances indésirables.
Voici un exemple:
Je ne vois vraiment pas si c'est possible mais bon, peut-être qu'il existe une petite astuce sympa pour ce genre de problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 // Dans Image.hxx qui ne serait pas exporté #include <header_indesirable.hpp> template<typename T> class Image { public: Image(){} void method(); // Méthode qui utilise header_indesirable.hpp private: T m_data; }; template<typename T> void method() { // du code } // Dans ImageImpl.hpp qui serait exporté typedef Image<int> ImageInt; typedef Image<float> ImageFloat;
Donc c'est ce que tu souhaites ? Je vais considérer que tu ne le souhaites pas
Je ne comprend toujours pas bien la question, mais il me semble que tu veux précompiler des templates non spécifiés et comme je l'ai écris avant il me semble que c'est impossible. Les templates sont utilisés à la compilation...
La liberté est à la sociologie ce que l'instant présent est à la physique relativiste.
Effectivement, je ne le souhaite pas ^^
Effectivement, je souhaite précompiler mes templates pour les cas que j'ai spécifié (des images en int et en float). Après, j'ai une solution, recoder la classe sans utilisé de template mais bon c'est un peu lourd ^^
Ok tout est clair maintenant
Donc je ne pense pas que ce soit possible mais attend la réponse d'un plus calé que moi. Le c++ est si tortueux... sait-on jamais...
La liberté est à la sociologie ce que l'instant présent est à la physique relativiste.
C'est possible.
Voici un exemple illustratif :
CartableCasse.h :
CartoucheCasse.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_CARTABLE_CASSE #define MODELE_PAS_DEFINI_DANS_ENTETE_CARTABLE_CASSE #include <iostream> class CartableCasse { public: void car() const { std::cout << "CartableCasse::car()\n"; } void table() const { std::cout << "CartableCasse::table()\n"; } void casse() const { std::cout << "CartableCasse::casse()\n"; } }; #endif
MonModele.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_CARTOUCHE_CASSE #define MODELE_PAS_DEFINI_DANS_ENTETE_CARTOUCHE_CASSE #include <iostream> class CartoucheCasse { public: void car() const { std::cout << "CartoucheCasse::car()\n"; } void touche() const { std::cout << "CartoucheCasse::touche()\n"; } void casse() const { std::cout << "CartoucheCasse::casse()\n"; } }; #endif
MonModele_impl.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_MON_MODELE #define MODELE_PAS_DEFINI_DANS_ENTETE_MON_MODELE template<class T> class MonModele { private: T m_data; public: void carcasse() const; void cartable() const; void cartouche() const; }; #endif
MonModeleCartableCasse.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_MON_MODELE_IMPL #define MODELE_PAS_DEFINI_DANS_ENTETE_MON_MODELE_IMPL #include "MonModele.h" template<class T> void MonModele<T>::carcasse() const { m_data.car(); m_data.casse(); } template<class T> void MonModele<T>::cartable() const { m_data.car(); m_data.table(); } template<class T> void MonModele<T>::cartouche() const { m_data.car(); m_data.touche(); } #endif
MonModeleCartoucheCasse.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #include "CartableCasse.h" #include "MonModele_impl.h" // Instancier les fonctions qui compilent pour T = CartableCasse : template void MonModele<CartableCasse>::carcasse() const; template void MonModele<CartableCasse>::cartable() const;
main.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #include "CartoucheCasse.h" #include "MonModele_impl.h" // Instancier les fonctions qui compilent pour T = CartoucheCasse : template void MonModele<CartoucheCasse>::carcasse() const; template void MonModele<CartoucheCasse>::cartouche() const;
Sortie :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include "MonModele.h" #include "CartableCasse.h" #include "CartoucheCasse.h" #include <iostream> int main() { MonModele<CartableCasse> foo; foo.carcasse(); foo.cartable(); std::cout << '\n'; MonModele<CartoucheCasse> bar; bar.carcasse(); bar.cartouche(); return 0; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 CartableCasse::car() CartableCasse::casse() CartableCasse::car() CartableCasse::table() CartoucheCasse::car() CartoucheCasse::casse() CartoucheCasse::car() CartoucheCasse::touche()
Bonjour,
En utilisant les extern template, et en forçant les instanciations on peut aussi le faire sur la classe entière
fichier .h
fichier .cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #ifndef DLLMASQUEE #define DLLIMP __declspec(dllimport) #else #define DLLIMP __declspec(dllexport) #endif template<class T> class DLLIMP Masquee { T x; public: Masquee(T const x) : x{ x } {} T action()const; };
On pourra alors utiliser les Masquee<> qui ont été instanciées dans la DLL.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #define DLLMASQUEE #include "Masquee.h" template<class T> T Masquee<T>::action()const { return 2 * x; } template class Masquee<int>; // forcer l'instanciation des cas int et float template class Masquee<float>;
Je me rends compte que mon exemple précédent était inutilement compliqué.
J'ai créé un exemple un peu plus simple qui utilise aussi l'astuce que viens de donner dalfab :
Car.h :
Cartable.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_CAR #define MODELE_PAS_DEFINI_DANS_ENTETE_CAR #include <iostream> class Car { public: void car() const { std::cout << "Car::car()\n"; } }; #endif
DoubleAction_light.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_CARTABLE #define MODELE_PAS_DEFINI_DANS_ENTETE_CARTABLE #include <iostream> class Cartable { public: void car() const { std::cout << "Cartable::car()\n"; } void table() const { std::cout << "Cartable::table()\n"; } }; #endif
DoubleAction.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_DOUBLE_ACTION_LIGHT #define MODELE_PAS_DEFINI_DANS_ENTETE_DOUBLE_ACTION_LIGHT #include <iostream> template<class T> class DoubleAction { private: T m_data; public: DoubleAction() { std::cout << "DoubleAction constructor\n"; } ~DoubleAction(); void doubleCar() const; void doubleTable() const; }; #endif
DoubleAction_Car_Cartable.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #ifndef MODELE_PAS_DEFINI_DANS_ENTETE_DOUBLE_ACTION #define MODELE_PAS_DEFINI_DANS_ENTETE_DOUBLE_ACTION #include "DoubleAction_light.h" template<class T> DoubleAction<T>::~DoubleAction() { std::cout << "DoubleAction destructor\n"; } template<class T> void DoubleAction<T>::doubleCar() const { m_data.car(); m_data.car(); } template<class T> void DoubleAction<T>::doubleTable() const { m_data.table(); m_data.table(); } #endif
Main.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include "Car.h" #include "Cartable.h" #include "DoubleAction.h" // Instancier les fonctions qui compilent pour T = Car : template DoubleAction<Car>::~DoubleAction(); template void DoubleAction<Car>::doubleCar() const; // Instancier toute la classe pour T = Cartable : template class DoubleAction<Cartable>;
Sortie :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "Car.h" #include "Cartable.h" #include "DoubleAction_light.h" #include <iostream> int main() { DoubleAction<Car> foo; foo.doubleCar(); std::cout << '\n'; DoubleAction<Cartable> bar; bar.doubleCar(); bar.doubleTable(); std::cout << '\n'; return 0; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 DoubleAction constructor Car::car() Car::car() DoubleAction constructor Cartable::car() Cartable::car() Cartable::table() Cartable::table() DoubleAction destructor DoubleAction destructor
Super!
Merci pour vos conseils!
Je viens de faire des tests et je vais utiliser la méthode de dalfab plutôt.
Voici mon petit exemple de test avec les fichiers CMake associés (j'ai testé sous Visual Studio 2010 et 2015).
ExportPreCompiledTemplate.zip
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager