2013-07-16 8 views
18

Benötige ich inline Vorlagenfunktionen, wenn sie in mehreren cpp Dateien enthalten sind? Vielen Dank.Inline-Vorlagenfunktion?

template<bool> inline QString GetText(); 
template<> inline QString GetText<true>() {return "true";} 
template<> inline QString GetText<false>() {return "false";} 
+0

Was Sie von 'inline' Template-Funktionen zu erhalten hoffen? – Oswald

+0

mögliches Duplikat von [Ist es sinnvoll, Inline-Schlüsselwort mit Vorlagen zu verwenden?] (Http://stackoverflow.com/questions/10535667/does-it-make-any-sense-to-use-inline-keyword-with -Templates) –

Antwort

21

Sie tun, weil diese volle Funktion Spezialisierungen sind, und daher unterliegen die One-Definition-Regel wie normale Funktionen.

+1

Für die Vorlage und nicht vollständig spezialisierte kann ich 'inline' Schlüsselwort entfernen . Ist es richtig? Wie 'Vorlage QString GetText();' – user1899020

+1

@ user1899020: Ja, Sie können. – Mehrdad

0

Es gibt keinen Grund für die Inline-für Template-Deklaration, aber nicht für Vorlage Voll Spezialisierung, brauchen Sie nicht das Schlüsselwort inline für die erste Zeile hinzufügen, aber die zweite und dritte brauchen. Jede Übersetzungseinheit, die die Vorlage verwendet, muss jedoch die Vorlagendefinition enthalten, so dass sie am besten in die Header-Datei aufgenommen und in andere cpps, die sie verwenden, einbezogen wird.

In C++ - Standard n3376 für 3.2/6 kann es mehr als eine Definition von Klassenvorlage für die gesamte Anwendung geben, vorausgesetzt, die Definition ist gleich.

===============

Aktualisieren Sie die answere Basis auf Jesse Gut Kommentare (müssen inline für Vorlage Voll sepcialization) Dank Jesse Guter Punkt, dass.

+0

Sie benötigen das Schlüsselwort 'inline'. Dies sind Vorlagen * Spezialisierungen * und würden ODR verletzen, wenn sie in mehreren Quelldateien enthalten wären. –

+2

Siehe '[temp.expl.spec]/12'" Eine explizite Spezialisierung einer Funktionsvorlage ist nur dann inline, wenn sie mit dem Inline-Spezifizierer deklariert ist oder als gelöscht definiert ist und unabhängig davon, ob ihre Funktionsvorlage inline ist. " – Mankarse

+0

@ZijingWu Sie beziehen sich auf einen Entwurf für C++ 14. In der aktuellen C++ 11 ist der relevante Abschnitt 3.2/5. Wenn Sie das vollständige Zitat eingefügt hätten, hätten Sie bemerkt, dass explizite Vorlagenspezialisierungen in diesem Abschnitt nicht als Ausnahmen erwähnt werden (weder in C++ 11 noch in C++ 14). – jogojapan

0

Es scheint, dass die Template-Methode in der gleichen Datei definiert werden muss, die erstellt wird. Sie müssen das Inline-Schlüsselwort nicht verwenden, da sie in jeder cpp-Datei erstellt wurden, die es enthält.

13

Ja, Sie benötigen die inline Spezifizierer dort.

Die ODR (Ein-Definition-Regel) besagt, dass es genau eine Definition einer Variablen, Funktion, Klasse, Enumeration oder Vorlage geben muss. Ausnahmen relevant für Ihre Frage in § 3.2/5 (C++ 11) (Hervorhebung von mir) aufgeführt:

Es kann mehr als eine Definition eines Klassentyps (Ziffer 9), Aufzählungstyp (7.2) , Inline-Funktion mit externer Verknüpfung (7.1.2), Klassenvorlage (Abschnitt 14), nicht statische Funktionsvorlage (14.5.6), statisches Datenelement einer Klassenvorlage (14.5.1.3), Elementfunktion einer Klassenvorlage (14.5.1.1) oder Template-Spezialisierung, für die einige Template-Parameter nicht angegeben sind (14.7, 14.5.5) in einem Programm vorausgesetzt, dass jede Definition in einer anderen Übersetzungseinheit erscheint und sofern die Definitionen die folgenden Anforderungen erfüllen. [...]

Template Spezialisierungen für die alle Parameter angegeben werden (dh explizite Spezialisierungen) sind dort nicht aufgeführt ist, und §14.7.3/12 sagt:

Eine explizite Spezialisierung von Eine Funktionsvorlage ist nur dann inline, wenn sie mit dem Inline-Spezifizierer deklariert oder als gelöscht definiert ist und unabhängig davon, ob ihre Funktion inline ist. [Beispiel:

template<class T> void f(T) { /∗ ... ∗/ } 
template<class T> inline T g(T) { /∗ ... ∗/ } 
template<> inline void f<>(int) { /∗ ... ∗/ } // OK: inline 
template<> int g<>(int) { /∗ ... ∗/ }   // OK: not inline 

- Ende Beispiel]

+0

Es scheint, dass 'template <> int g <> (int) {/ * ... * /}' in meinem Test das Schlüsselwort 'inline' benötigt. – user1899020

+0

@ user1899020 Haben Sie tatsächlich die Antwort gelesen? Wenn Sie es in mehrere CPP-Dateien einfügen, die miteinander verknüpft sind, dann benötigen Sie Inline. Das sagt das Beispiel (welches aus dem Standard stammt). – jogojapan