60 votes

Comment forcer une instance particulière d'un modèle C++ à s'instancier ?

Voir le titre. J'ai un modèle. Je veux forcer l'instanciation d'une instance particulière d'un modèle. Comment dois-je m'y prendre ?

Plus précisément, peut-on forcer une classe modèle abstraite à s'instancier ?


Je pourrais élaborer car je me pose la même question. Dans mon cas, je construis une bibliothèque. Certaines implémentations de modèles sont volumineuses et comprennent beaucoup de choses, mais ne sont générées que pour quelques types. Je veux les compiler dans la bibliothèque et exporter toutes les méthodes, mais ne pas inclure l'en-tête avec le code partout.

ie :

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 référencer toutes les méthodes dans la bibliothèque, ce qui les forcerait à compiler et à exporter, mais le but n'est pas d'ajouter du code inutile à la bibliothèque, comme le formatage des arguments pour les éléments et le code pour les appeler, etc.

? ???? Plus précisément, je construis la bibliothèque pour plusieurs versions de MSC et des compilateurs GCC et intel.

73voto

Vous pouvez également essayer l'instanciation explicite :

template class vector<int>;                    // class
template int& vector<int>::operator[](int);    // member
template int convert<int,double>(double);      // function

66voto

Georg Fritzsche Points 59185

Vous ne pouvez pas forcer les templates génériques à s'instancier, le compilateur ne peut générer du code que si le type est complètement connu.

Pour forcer une instanciation, il faut fournir tous les types explicitement :

template class std::vector<int>;

Comeaus FAQ sur les modèles couvre les questions connexes de manière assez détaillée.

1voto

sth Points 91594

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 quelque part, 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.

0voto

antonm Points 1869

Si je comprends bien votre question, vous avez une classe template, et vous voulez forcer le compilateur à générer le code pour une utilisation avec un type spécifique. Par exemple, vous pouvez vouloir vous assurer que le code pour std::vector<int> existe dans votre programme.

La meilleure façon de s'en assurer est de construire simplement une instance de la classe :

void EnsureInstantiation()
{
    std::vector<int> intvector;
    std::vector<boo> boolvector;
    /// etc.
}

L'astuce est que vous n'avez même pas besoin d'appeler EnsureInstantiation dans votre code. Assurez-vous simplement qu'il n'est pas statique, sinon le compilateur mai l'optimiser.

-3voto

Anycorn Points 20521

La classe abstraite ne peut pas être instanciée. Vous voulez probablement faire quelque chose du genre :

Abstract *a = new Implementation(...);

Pour forcer l'instanciation du modèle, appelez le modèle avec les paramètres du modèle :

std::max<int>(...);
std::pair<int, string>(...);

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