C++ Templates in ausgelagerten Dateien

meisteralex

Lieutenant
Registriert
Juni 2003
Beiträge
552
Hi Leute,
ich hab hier eine Sache mit Template - Programmierung, wo ich in einer ausgelagerten Datei eine template - Funktion schreibe, welche ich dann durch includieren der Headerdatei in mein main-Programm einfüge.

Sprich in der ausgelagerten Datei, wird meine Funktion "vorcompiliert" und steht dort nur noch als Kombination von Headerdatei und Objectdatei zur Verfügung. Dies bringt nur das Problem mit sich, dass in der Objektdatei natürlich nicht die in main benötigten Ausprägungen der Funktion vorhanden sind.
Meine einzige Lösung war bis jetzt die komplette Funktion in der Headerdatei zu implementieren, es muss da jedoch noch eine andere Möglichkeit geben.
Nach dem was ich bisher gehört habe, soll man in der Headerdatei angeben können, mit welchen Parametertypen man das Template mal benötigen könnte und diese werden dann auch so in die Objectdatei ausgeprägt.

Weißt jemand genau wie das geht ?
 
was meinst du denn mit ausprägungen? ich versteh den sinn nicht ganz bzw. was du allgemein vor hast. du schreibst das template in eine header-datei (oder cpp, je nachdem was dort noch drin steht) und dort spezialisierst du ebenso für gewisse fälle.

beispiel:
Code:
double fmod(double a, double b) {
  int result = static_cast<int>( a / b );
  return a - static_cast<double>( result ) * b;
}

// Generelles Template
template<typename T> T mod( T x, T y ) {
  return x % y;
}

// Spezialisierung für T = double
template<double> float mod( double x, double y ) {
  return fmod( x, y );
}

dies muss hier z.b. nur gemacht werden, da der modulo operator nur auf int ableger angewendet kann und nicht auf gleitkommazahlen. oder meinst du gänzlich was anderes?
 
also nochmal (ich glaub wir reden aneinander vorbei):

ich habe meine template-funktions-definition ausgelabger in eine seperate datei, diese wird ja vorkompiliert und als objectdatei bereitgestellt

wenn ich nun in meinem eigentlichem programm die template funktion auf verschiedene weisen verwenden, kann der compiler ja im vorhinen nicht gewusst haben, wie er diese funktion "auszuprägen" hat, sprich in der objektdatei steht die entsprechende funktion nicht bereit

ich suche nun einen weg in der headerdatei der funktionsdefinition zu sagen "hallo lieber compiler, ich brauche diese template - funktion wahrscheinlich mal in den ausführungen, wo ich als argument integer, bool oder string übergeben, bitte präge die funktion doch auf diese weisen aus, wenn du mir aus meinem ausgelagertem code die objectdatei erzeugt, damit ich die funktionen dann hinterher auch in der objectdatei habe"
 
Mit dem aneinander vorbei reden, ist bei der Schilderung auch nicht all zu schwierig. Hier werde ich die Glaskugel mal polieren, vielleicht gibt dann einen Treffer.
Für Dummies:
Es liegt ein nicht änderbares Template vor.
Dieses Template generiert auf Grund von ... neuen Code, neue Templates ... zum Compilierzeitpunkt.

Das fällt in die Rubrik Meta-Programmierung (Google hilf).

Bei C++ ist das ein noch recht exotisches Thema und fällt oft in die Kategorie elegantes Programmieren in akademischen Zirkeln, oder der Prof ist heute besonders gemein. In freier Wildbahn kenne ich diesbezüglich nur die C++ boost Bibliothek wo so etwas verwendet wird.
Nun zu den Ausprägungungs...........
Der Trick an der Sache ist, dass der Compiler mindestens zwei Durchläufe macht.
Im ersten erzeugt er mit dem feststehenden Template den 'neuen Code / Template' und im zweiten übersetzt er den neuen Code....
Im Resultat ist von dem ursprünglichen Template natürlich nichts mehr vorhanden, weil dafür ja der generierte Code übersetzt wurde.
 
Hallo,

das geht mit dem Schlüsselwort export.

Allerdings unterstützt lediglich ComeauC++ dieses Schlüsselwort, es ist unterspeziert und birgt große Gefahren bei seiner Verwendung, die die Semantik der Sprache gefährden können. Daher - nicht benutzen. Wenn du den Comeau-Compiler nicht hast, klappt es eh nicht.

Eine Alternative wären explizite Instanziierungen. Dann musst du für jede Ausprägung des Templates den Typ benennen, für den es instanziiert werden soll. Ich hab die Syntax gerade nicht im Kopf, eine (Google-)Suche nach expliziter Instanziierung bzw. explicit instanciation sollte dich schnell ans Ziel führen. Diese Variante ist allerdings insofern beschränkt, dass du eben alle Typen bereits im Vorfeld in der entsprechenden Übersetzungseinheit kennen und benennen musst.

Ansonsten bleibt dir nur der normale Weg, Templates in Headern zu deklarieren und zu definieren.

(P.S.: die Glaskugel habe ich nicht gebraucht, stand doch alles da...)
 
@7H3 N4C3R Intel C/C++ ab Version 8.1 (Linux und Mac) unterstützt 'export'.

(P.S.: Hut ab vor deinen interpretativen Fähigkeiten)
 
@7H3 N4C3R Der Intel hat auch das EDG - Frontend. Seit der Version 8.1 ist exports enabled (siehe dein erster Verweis) ... Alles Weitere wären von meiner Seite lediglich Vermutungen. Die Unterschiede könnten in der verwendeten Version des EDG - Frontends liegen.

Siehe 'Intel C++ Compiler User and Reference Guide (aktuelle Linux Version Seite 84)
----------------------
Conformance to the C++ Standard
The Intel® C++ Compiler conforms to the ANSI/ISO standard (ISO/IEC
14882:1998) for the C++ language.
Exported Templates
The Intel® C++ Compiler supports exported templates using the following
options: -export
Enable recognition of exported templates. Supported in C++ mode only.
---------------------------------
Für 'non commercial' kannst du dir den Intel - Compiler für Linux auch kostenlos herunterladen......
 
Zuletzt bearbeitet:
@meisteralex

Ich hab gerade (mal wieder) das gleiche Problem gehabt, und es in VS2005 folgendermaßen gelöst:

Datei temp.h:
-----------------

template <class T> class A
{
A(); // Deklaration eines Konstruktors
...
};

#include "temp.impl.h"


Datei temp.impl.h:
-----------------------

template <class T> A<T>::A() {} // Definition des Konstruktors


So hat man zwar weiterhin alles in Header-Dateien, die aber in Deklaration und Definition getrennt sind.
 
Zurück
Oben