2015-05-27 11 views
7

Ich möchte alle impliziten Template-Instanziierungen für eine bestimmte Template-Klasse verhindern, um zu verhindern, dass sie in jede Übersetzungseinheit instanziiert wird.Wie verhindere ich implizite Template-Instanziierungen für eine bestimmte Vorlage?

Es sieht aus wie meine Optionen sind:

  1. Verwenden -fno-implizite-Vorlagen auf Befehlszeile des gcc. Diese unterdrückt alle impliziten Template-Instanziierungen und ist nicht was ich will. Ich möchte das nur für eine einzelne Vorlage verhindern.
  2. Verwenden Sie C++ 11 "externe Vorlage". Dies unterdrückt jedoch nur explizite explizite Instanziierungen. Ich möchte nicht eine "extern Vorlage" Zeile für jede mögliche Vorlage Parameterliste geben diese Vorlage könnte instanziiert werden mit.

Also brauche ich etwas dazwischen. Es wäre schön zu haben:

extern template class Foo; // suppress all implicit instantiations of Foo 

(Beachten Sie das Fehlen von Template-Parameter (n).) Irgendwelche Ideen?

+0

Was ist der Anwendungsfall? Möchten Sie verhindern, dass bestimmte Instanziierungen überhaupt verwendet werden, oder einfach nur versuchen, den Speicherplatz für Objektdateien und die Verknüpfungszeit zu sparen? – user657267

+0

Ich versuche, die Kompilierzeit zu speichern. Es macht einen großen Unterschied in diesem Fall. Und obwohl ich die Disassemblierung gelegentlich durchkämmen könnte, um neue Instanzen zu finden, die explizit extern dargestellt werden müssen, würde ich bevorzugen, dass der Linker nur einen Fehler bei neuen impliziten Instanziierungen macht, damit sie sofort zur Liste der Expliziten hinzugefügt werden können Instanziierungen durch die Person, die die kausale Modifikation macht. –

+8

Sie könnten die Vorlagendefinition zwischen einer Kopf- und einer Quelldatei wie bei einem Nicht-Template aufteilen. Wenn Sie die Vorlage für die Gruppe der zulässigen Typen in der Quelldatei nicht explizit instanziieren, schlägt die Verknüpfung fehl. – Praetorian

Antwort

1

Ich würde sagen, dass die Antwort auf Ihre Frage ist mit C++ neuen Typ Züge die instantiations in Ihrem Konstruktor zu behaupten:

static_assert(std::is_same<TInstantiation, [your-predefined-type]> || std::is_same<TInstantiation, [your-predefined-type2]> /*And so on...*/, "Classname can not be instantiated using this type!"); 

Es ist alles bei der Kompilierung lösen garantiert :)

1

können Sie Teilen Sie die Klasse wie bei einer Nicht-Template-Klasse. Fügen Sie die Deklarationen einfach in eine Kopfzeile ein und fügen Sie diese überall ein und fügen Sie die Implementierung in eine .inl/.i-Datei ein und fügen Sie diese nur dort ein, wo Ihre Vorlage instanziiert werden soll. Alternativ können Sie die Kompilierzeitschalter dazu verwenden, um dies mit einer einzigen Datei zu tun - Sie müssen jedoch Deklaration und Implementierung trennen.

1

können Sie std::enable_if verwenden, die genau das tut dies mit der Kombination von std::is_same:

template <class T , typename = std::enable_if <!std::is_same<T,Foo>::value,T>::type > 
class MyClass{ 
//... 
}; 

jetzt myClass nicht für Foo Typ zusammengestellt werden.

Verwandte Themen