Comment forcer une instance particulière D'un modèle C++ à instancier?
voir titre. J'ai un modèle. Je veux forcer une instance particulière d'un modèle à instancier. Comment dois-je faire?
plus spécifiquement, pouvez-vous forcer une classe de template abstrait à instancier?
je pourrais développer car j'ai la même question. Dans mon cas, je construis une bibliothèque, certaines implémentations de template sont grandes et incluent beaucoup de choses, mais ne sont générées que pour quelques types. Je veux pour les compiler dans la bibliothèque et exporter toutes les méthodes, mais ne pas inclure l'en-tête avec le code partout.
c'est à dire:
template<class T>
OS_EXPORT_DECL class MyTmpl
{
T *item1;
public:
inline T *simpleGetT() { return(item1); } /* small inline code in here */ }
T *doSomeReallyBigMergeStuff(T *b); // note only declaration here
};
// *** implementation source file only seen inside library
template<class T>
MyTmpl<T>::doSomeReallyBigMergeStuff(T *b)
{
... a really big method, but don't want to duplicate it,
so it is a template ...
}
je pourrais bien sûr faire référence à toutes les méthodes à l'intérieur de la bibliothèque qui les forceraient à compiler et exporter, mais le désir n'est pas d'ajouter du code non nécessaire à la bibliothèque comme l'argument formatage pour les articles et le code pour les appeler etc.
????? plus précisément, je construis la bibliothèque pour plusieurs versions de compilateurs MSC et GCC et intel.
6 réponses
vous ne pouvez pas forcer les gabarits génériques à instancier, le compilateur ne peut générer du code que si le type est complètement connu.
Forcer l'instanciation se fait en fournissant tous les types explicitement:
template class std::vector<int>;
Comeaus template FAQ couvre les questions connexes en détail.
ce que vous pouvez également essayer est une instanciation explicite:
template class vector<int>; // class
template int& vector<int>::operator[](int); // member
template int convert<int,double>(double); // function
Vous pouvez forcer l'instanciation en utilisant le modèle avec le paramètre souhaité. Par exemple, vous pouvez définir une fonction en utilisant toutes les méthodes requises:
void force_int_instance() {
Abstract<int> *a;
a->some_method();
a->some_other_method(1, 2, 3);
}
vous n'avez pas besoin d'appeler cette fonction n'importe où, donc ce n'est pas un problème que le pointeur ne soit pas initialisé. Mais le compilateur doit supposer que la fonction peut être appelée à partir d'un autre fichier objet, il doit donc instancier le modèle.
si je comprends bien votre question, vous avez une classe template, et vous voulez forcer le compilateur à générer le code à utiliser avec un type spécifique. Par exemple, vous pouvez vouloir s'assurer que le code pour std::vector
la meilleure façon d'assurer cela est de simplement construire une instance de la classe:
void EnsureInstantiation()
{
std::vector<int> intvector;
std::vector<boo> boolvector;
/// etc.
}
l'astuce est que vous ne devez même pas appeler EnsureInstantiation n'importe où dans votre code. Il suffit de s'assurer qu'il n'est pas statique ou bien le compilateur peut l'optimiser.
classe abstraite ne peut pas être instanciée.vous voulez probablement faire quelque chose du genre:
Abstract *a = new Implementation(...);
pour forcer l'instanciation de template, appeler template avec les paramètres de template:
std::max<int>(...);
std::pair<int, string>(...);
je vais répondre à ce que je pense que vous vouliez dire, pas ce que vous avez dit.
je suppose que la question Est l'une de deux choses. La première est que vous avez du code dans un template qui n'est pas compilé lorsque vous compilez le fichier template lui-même, ce qui peut être très ennuyeux. Cela peut être corrigé dans les paramètres de votre compilateur.
L'autre c'est que vous voulez avoir quelque chose de spécial pour un type particulier, peut-être pour le déboguer. Qui est appelé instanciation explicite mais ne pas vraiment instanciate quoi que ce soit juste s'assure qu'il est toujours défini après ce point.