C++ 03 und C++ 11 hat im ersten Absatz von [temp.friend]:Freund eine Vorlage Spezialisierung ohne <>
[Bearbeitet Zitat. Erster Versuch verpassten einen zweiten Unterschied in der Formulierung]
Für eine Freund Funktionsdeklaration, die keine Template-Deklaration ist.
, wenn der Name des Freundes ein qualifizierter oder unqualifizierter ist Template-id, bezieht sich die Erklärung auf eine Freund Spezialisierung einer Funktionsschablone, sonst
, wenn der Name des Freundes, eine qualifizierte ID und eine passenden nichtcodierende FKT -Ion in der angegebenen Klasse oder Namensraum gefunden wird, bezieht sich die Freund Erklärung für diese Funktion, andernfalls
[C++ 03:], wenn der Name des Freundes ist eine qualifizierte ID und eine passende Spezialisierung eine Funktion Vorlage wird in der angegebenen Klasse oder Namespace, der Freund Erklärung bezieht
diese Funktion Vorlage Spezialisierung, andernfalls[C++ 11:] zu finden ist eine qualifizierte Nummer, wenn der Name des Freundes und und Eine passende Funktionsschablone wird in der angegebenen Klasse oder dem angegebenen Namespace gefunden. Die Friend-Deklaration bezieht sich auf die abgeleitete Spezialisierung dieser Funktionsschablone, andernfalls
Der Name soll eine unqualifizierte ID sein, die eine normale (Nintemplate) Funktion deklariert (oder deklariert).
[Die Änderung in der Formulierung scheint mir, wie Klarstellung. Obwohl ich denke, dass es verschiedene Möglichkeiten geben könnte, die C++ 03-Formulierung über "eine Spezialisierung in einer Klasse oder einem Namespace zu finden" zu interpretieren.]
Ich bin neugierig auf diese dritte Kugel. Ich schrieb diesen Code zu versuchen, seine Anforderungen zu entsprechen, aber beide g ++ 4.8.1 und Klirren ++ 3.4 lehnen den Code, ob mit -std = C++ 03 oder -std = C++ 11:
template <class T> class R;
namespace N {
template <class T> void test(const R<T>&);
}
template <class T>
class R {
friend void N::test(const R<T>&); // 8
int m;
};
template <class T>
void N::test(const R<T>& rec) { rec.m; }
int main() {
R<int> r;
N::test(r);
}
Of Natürlich, wenn ich Linie 8 zu
friend void N::test<>(const R<T>&);
die erste Kugel ändert gilt und das Programm akzeptiert wird. g ++ gibt eine hilfreiche Warnung aus, die besagt, dass der Freund "eine Nicht-Template-Funktion deklariert" und vorschlägt, dass ich genau das tun möchte. Der Code würde wahrscheinlich mehr Stilpunkte für Klarheit und Sicherheit bekommen.
Aber sollte nicht der obige Code von der dritten Kugel abgedeckt und gültig sein? Die Friend-Deklaration ist keine Template-Deklaration und verwendet eine qualifizierte ID, die keine Template-ID als Name ist. Und es gibt keine Nintemplate-Funktionsdeklaration für das zweite Aufzählungszeichen.
Ist das nur ein Compilerfehler, der beiden gemeinsam ist? Oder habe ich etwas missverstanden, und wenn ja, gibt es ein Beispiel für ein Programm, das diese dritte Kugel vorführt?
+1 Interessant. Ich vermute, dass '<>' Teil des "Namens des Freundes" ist. –
@JohnDibling: * qualifizierte-ID * enthält unter anderem * Template-ID *, also ja, 'f <>' ist eine * qualifizierte-ID * insgesamt. –
@JohnDibling Ja, die Token '<' and '>' sind Teil der _template-id_. Ein _name_ kann ein _identifier_, _operator-function-id_, _literal-operator-id_, _conversion-function-id_ oder _template-id_ [basic/4] sein. – aschepler