2013-01-04 5 views
5

sagen, dass ich eine Template-Klasse A in a.hWarum Position expliziter Vorlage Instanziierung Materie

#include <iostream> 

template<bool b> 
class A { 
public: 
    void print(std::ostream& out); 
}; 

erklären und die Druckmethode in a.cpp (mit expliziter instatiation für true und false)

#include "a.h" 

template<bool b> 
void A<b>::print(std::ostream& out) { 
    out << "A" << b; 
} 

template class A<true>; 
template class A<false>; 

definieren Ein Beispiel für ein Hauptprogramm in main.cpp könnte

sein

Das kleine Projekt oben kompiliert einfach gut.

Frage: Wenn ich die expliziten Instanziierungen über der Definition des Verfahrens print setzen (in a.cpp), wird der Code nicht mehr kompilieren, mit den üblichen undefined reference to A<true>::print(...) Fehlern.

#include "a.h" 

template class A<true>; 
template class A<false>; 

template<bool b> 
void A<b>::print(std::ostream& out) { 
    out << "A" << b; 
} 

Warum ist das der Fall?

bearbeiten: Makefile

main : main.o a.o 
    g++ main.o a.o -o main 

main.o : main.cpp 
    g++ -c main.cpp 

a.o : a.cpp 
    g++ -c a.cpp 
+1

funktioniert auch auf VS2012. – billz

+0

Ich habe und ich änderte die Reihenfolge als Dejan erwähnt – billz

+1

@jogojapan - +1. Ich habe meinen Kommentar gelöscht, der besagt, dass er mit clang32 und gcc48 kompiliert wird. Es wurde mit jedem Compiler und mit beliebiger Reihenfolge kompiliert, wenn der Inhalt von drei Dateien ausgeschnitten und in eine Datei eingefügt wurde - wie ich es ursprünglich für meinen Test getan hatte. Nachdem Dejan Makefile gepostet hatte, konnte ich Fehler mit clang und gcc jeder Version reproduzieren. –

Antwort

8

Ich glaube nicht, dass es eine gute natürliche Erklärung dafür gibt, warum das so ist. Offensichtlich könnte der Compiler die Definition der Elementfunktion sehen, selbst wenn sie nach der expliziten Instanziierung – bereitgestellt wird, da sie sich in derselben Datei befindet.

Compiler sind jedoch nicht erforderlich; es ist in der Tat ausdrücklich von der Norm verboten:

(§14.7.2/9) Eine explizite Instanziierung Definition, die Namen eine Klasse Template-Spezialisierung explizit die Spezialisierung Klassenvorlage instanziiert und ist eine explizite Instanziierung Definition nur diejenigen Mitglieder die zum Zeitpunkt der Instanziierung definiert wurden.

Ich denke, die Gründe dafür sind folgende:

  • Es für einige der Mitgliedsfunktionen später in der Übersetzungseinheit mehrere verschiedene explizite Spezialisierungen sein könnte; es macht auch im Interesse des Programmierers Sinn, eine explizite Regel darüber zu haben, welche davon instanziiert wird;

  • Wenn eine Vorlage implizit instanziiert wird, werden nur Spezialisierungen berücksichtigt, die vor dem Instanziierungszeitpunkt definiert wurden. Die Regel ist also für implizite und explizite Instanziierungen gleich.

1
template class A<true>; 
template class A<false>; 

Die gleichen Grund zu kompilieren, warum es in der Regel Code wird erwartet, dass Vorlage im Header definiert ist selbst. Um explizite Instanziierung durchzuführen, müssen Sie (der Compiler) die gesamte Definition der Vorlagenklasse sehen können, die von Ihrem main.cpp nicht möglich ist.

Allerdings hat a.cpp Zugang zu allen der Definition der Klasse (hier die Druckmethode), so dass explizite Instanziierung dort funktioniert.

+0

Ich bin mir nicht sicher, ob ich deine Antwort verstehe. Meine Verwirrung besteht in der Neuordnung von Anweisungen in 'a.cpp'. –

+0

@ DejanJovanović: ah mein Missverständnis, dann sieht es aus wie eine Compiler-Sache, es funktioniert auf VS2010 –

Verwandte Themen