web-dev-qa-db-de.com

Wie erzwinge ich, dass eine bestimmte Instanz einer C++ - Vorlage instanziiert wird?

Titel sehen Ich habe eine Vorlage. Ich möchte, dass eine bestimmte Instanz einer Vorlage instanziiert wird. Wie mache ich das?

Können Sie insbesondere eine abstrakte Vorlagenklasse zum Instanziieren zwingen?


Ich könnte etwas näher ausführen, da ich dieselbe Frage habe. In meinem Fall baue ich eine Bibliothek. Einige der Implementierungen von Vorlagen sind umfangreich und enthalten viele Elemente, werden jedoch nur für einige Typen generiert. Ich möchte sie in der Bibliothek kompilieren und alle Methoden exportieren, aber den Header nicht überall mit Code einfügen.

dh:

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 ...
}

Ich könnte natürlich auf alle Methoden in der Bibliothek verweisen, die sie zwingen würden, zu kompilieren und zu exportieren, aber der Wunsch besteht nicht darin, nicht benötigten Code zur Bibliothek hinzuzufügen, wie die Argumentformatierung der Elemente und der Code, um sie aufzurufen usw.

????? Ich baue gerade die Bibliothek für mehrere Versionen von MSC und GCC- und Intel-Compilern.

46
anon

Sie können generische Vorlagen nicht zwingen, zu instanziieren, der Compiler kann Code nur generieren, wenn der Typ vollständig bekannt ist.

Das Erzwingen einer Instantiierung erfolgt durch explizite Angabe aller Typen:

template class std::vector<int>;

Comeaus template FAQ behandelt die verwandten Probleme detailliert.

51
Georg Fritzsche

Was Sie auch ausprobieren können, ist die explizite Instantiierung:

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

Sie können die Instantiierung erzwingen, indem Sie die Vorlage mit dem gewünschten Parameter verwenden. Sie können beispielsweise eine Funktion mit allen erforderlichen Methoden definieren:

void force_int_instance() {
  Abstract<int> *a;
  a->some_method();
  a->some_other_method(1, 2, 3);
}

Sie müssen diese Funktion nicht überall aufrufen, es ist also kein Problem, dass der Zeiger nicht initialisiert wird. Der Compiler muss jedoch davon ausgehen, dass die Funktion möglicherweise aus einer anderen Objektdatei aufgerufen wird, und muss daher die Vorlage instanziieren.

1
sth

Wenn ich Ihre Frage richtig verstanden habe, haben Sie eine Vorlagenklasse und möchten, dass der Compiler den Code generiert, der mit einem bestimmten Typ verwendet werden soll. Sie möchten beispielsweise sicherstellen, dass der Code für std :: vector <int> in Ihrem Programm vorhanden ist.

Um dies sicherzustellen, erstellen Sie einfach eine Instanz der Klasse:

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

Der Trick ist, dass Sie EnsureInstantiation nicht überall im Code aufrufen müssen. Stellen Sie nur sicher, dass es nicht statisch ist, oder der Compiler may optimiert es.

0
Anton