2010-03-19 8 views
8

Warum hat den folgenden gibt keinen Übersetzungsfehler ?:Keine "Neudefinition des Standardparameterfehlers" für die Memberfunktion der Klassenvorlage?

// T.h 

template<class T> class X 
{ 
public: 
    void foo(int a = 42); 
}; 

// Main.cpp 

#include "T.h" 
#include <iostream> 

template<class T> void X<T>::foo(int a = 13) 
{ 
    std::cout << a << std::endl; 
} 

int main() 
{ 
    X<int> x; 
    x.foo(); // prints 42 
} 

Es scheint, als ob die nur vom Compiler automatisch ignoriert wird. Warum ist das?
Die Cooky-Sache ist, dass, wenn die Klassenvorlage Definition ist in Main.cpp anstelle einer Header-Datei, bekomme ich tatsächlich die Standardparameter Neudefinition Fehler.

Jetzt weiß ich, der Compiler wird sich darüber beschweren, wenn es nur eine gewöhnliche (nicht Vorlage) Funktion wäre.

Was sagt der Standard zu Standardparametern in Memberfunktionen oder Funktionsschablonen von Klassenschablonen?

+1

g ++ * bricht die Kompilierung mit einem Fehler ab. – sth

+0

Wenn Sie sagen "... wenn die Template-Deklaration in ... ist" nehme ich an, dass Sie die Definition der Klassenvorlage meinen, also 'template class x {....};'. Wenn ja, dann sagen Sie, dass das Ersetzen der Include-Direktive durch diese Template-Klassendefinition eine andere Compiler-Nachricht erzeugt? Das deutet darauf hin, dass es etwas anderes in der Header-Datei gibt, d. H., Versuchen Sie, den gesamten Inhalt der Header-Datei dorthin zu kopieren, wo die include-Anweisung war, und vermutlich erhalten Sie dann keine Compiler-Warnung? – Troubadour

+0

Es könnte irgendwie auf diesen VC++ - Fehler bezogen werden: https://connect.microsoft.com/VisualStudio/feedback/details/496593/msdn-forum-splitting-templated-function-with-default-argument-into-declaration-definition -gives-compilation-error –

Antwort

3

8.3.6 §6 Die Standardargumente in einer Funktionsdefinition, dass außerhalb der Klasse Definition befindet sich auf den Satz von Standardargumente von der Mitgliedsfunktion Deklaration in der Klasse bereitgestellt werden hinzugefügt Definition.
[Beispiel:

class C { 
    void f(int i = 3); 
    void g(int i, int j = 99); 
}; 
void C::f(int i = 3) // error: default argument already 
{ }     // specified in class scope 
void C::g(int i = 88, int j) // in this translation unit, 
{ }       // C::g can be called with no argument 

--end Beispiel]

Nach der Norm, soll es einen Fehler geben.

+3

@tusbar Sie zitieren nur einen Teil dieses Absatzes. Es steht am Anfang davon "Außer Mitgliederfunktionen von Klassenvorlagen, ...". –

+4

Interessant: C++ 03 unterscheidet sich von C++ 98. Was @tusbar zitiert, ist der C++ 98-Text, während C++ 03 die Ausnahme für Klassenvorlagen hinzugefügt und dem Absatz hinzugefügt wurde. "Standardargumente für eine Elementfunktion einer Klassenvorlage sollen in der ursprünglichen Deklaration der Elementfunktion angegeben werden innerhalb der Klassenvorlage. " - Ich vermute, dass dies im Falle von Mitgliedern von Klassenvorlagen das Verbot von Standardargumenten in nicht-definierten Definitionen bedeuten soll, indem man sagt, dass alle Standardargumente innerhalb der Klasse angegeben werden sollten unklar (verbietet es Duplikate?). –

+1

Ich schaute in http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html # 217 und es scheint, als ob die Absicht besteht, keine Standard-Ranglisten für Template-Mitglieder zu verbieten. Außerdem denke ich jetzt, da das außerhalb der Klasse liegende Standardargument als von der Klasse in der Klasse getrennt betrachtet wird, selbst wenn es lexikalisch identisch ist, es die Einschränkung "soll in der anfänglichen Deklaration angegeben werden" verletzt. Das macht also Sinn, wenn Sie einen Kompilierzeitfehler bekommen. Die "Ausgabe 3.13", auf die sich John Spicer bezieht, kann in diesem Dokument nachgelesen werden: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0607.pdf –

Verwandte Themen