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.

43
demandé sur peterk 2010-01-28 06:01:43

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.

47
répondu Georg Fritzsche 2013-07-22 11:35:15

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
41
répondu Alexander Poluektov 2010-01-28 15:50:13

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.

1
répondu sth 2010-01-28 03:31:08

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 existe dans votre programme.

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.

0
répondu Anton 2010-01-28 03:27:12

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>(...);
-1
répondu Anycorn 2010-01-28 03:10:55

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.

http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc16explicit_instantiation.htm

-2
répondu Charles Eli Cheese 2010-01-28 07:09:12