2016-10-09 4 views
0

dort:Spezialisierung der Elementfunktion der Vorlagenklasse

Was ist das Ergebnis der folgenden Codes?

foo.h

#include <iostream> 

template<class _Tp> 
struct Foo 
{ 
    void print() { std::cout << "foo\n"; } 
}; 

foo.cxx

#include "foo.h" 

template<> 
void Foo<int>::print() 
{ 
    std::cout << "foo<int>\n"; 
} 

main.cxx

#include "foo.h" 

int main() 
{ 
    Foo<double>().print(); 
    Foo<int>().print(); 
    return 0; 
} 

Die Ergebnisse sind unterschiedlich:

  1. , wenn sie von MSVC erfüllt,

    foo 
    foo 
    
  2. , wenn sie von g ++ kompiliert,

    foo 
    foo<int> 
    

Ich möchte das zweite Ergebnis unabhängig von Compiler erhalten. Was soll ich zusätzlich tun? Wenn möglich, würden Sie mir eine Erklärung zu den zugrunde liegenden Standards oder Mechanismen geben. Vielen Dank!

+2

Das "Ergebnis der folgenden Codes" ist ein Kompilierungsfehler in foo.cxx, da es keinen gültigen C++ - Code enthält. –

+0

Ich habe geändert falsch eingegeben: void Foo :: void print() -> void Foo :: print() Würden Sie wieder sehen, danke. –

+0

Sie müssen nur die Spezialisierung in der Header-Datei deklarieren, so dass sie in allen Übersetzungseinheiten sichtbar ist. Fügen Sie eine 'Vorlage <> void Foo :: print();' Deklaration in die Header-Datei hinzu. –

Antwort

1

Ihr Programm hat ein undefiniertes Verhalten.

Es gibt zwei Implementierungen von Foo<int>::print() - eine Inline-Definition, die aus der Klassenvorlagedefinition und der Nicht-Inlinedefinition in foo.cxx stammt. Ein Compiler kann frei wählen.

Ein Compiler ist nicht erforderlich, um dies als ein Problem zu diagnostizieren. Viele von ihnen (anscheinend einschließlich g ++ und MSVC) wählen diese Route für Definitionen von Klassenvorlagen und ihren Mitgliedsfunktionen.

Um sicherzustellen, dass beide Compiler die Implementierung in foo.cxx auswählen, deklarieren Sie die Funktion in foo.h.

#include <iostream> 

template<class _Tp> 
struct Foo 
{ 
    void print() { std::cout << "foo\n"; } 
}; 

template<> void Foo<int>::print(); 
+0

Danke, aber es gibt einen Link Fehler: _unresolved externe Symbole_ in MSVC, wo es in g ++ OK ist. –

+0

@DongikShin, meine erste Reaktion ist, dass vielleicht foo.Cxx ist nicht Teil des Builds. Wenn foo.cxx Teil des Builds ist, kann ich den Linker-Fehler nicht erklären. –

0

Es ist interessant. Ich weiß, dass Vorlagen zum Zeitpunkt der Kompilierung interpretiert werden, nicht Link Zeit. Daher sollte meiner Meinung nach die Spezialisierungsvorlage bei jeder cpp-Datei implementiert werden. Was ist deine g ++ Version?

0

Wenn die foo.h wie folgt aussieht, produzieren beide Compiler die gleichen Ergebnisse. Aber ich weiß nicht warum.

#include <iostream> 


template<class _Tp> 
struct Foo 
{ 
    void print(); 
}; 

template<class _Tp> 
void Foo<_Tp>::print() 
{ 
    std::cout << "foo\n"; 
} 

template<> void Foo<int>::print(); 
Verwandte Themen