Ich habe dieses Problem in einem echten C ++ 11 Code kennengelernt, aber ich habe es auf den Punkt gebracht:
%Vor% Ich habe versucht, eine Out-of-Line-Definition einer Template-Member-Funktion einer Template-Klasse zu erstellen, wobei die Signatur der Funktion eine andere Template-Member-Funktion aufruft und mit etwas wie der not_working()
-Funktion beginnt. Das Problem war, dass die Definition nicht mit der Deklaration übereinstimmt.
Clang sagte:
%Vor%GCC sagte:
%Vor% Durch Versuch und Irrtum habe ich festgestellt, dass ich mit einem nachgestellten Rückgabetyp die Definition so erhalten könnte, dass sie mit der Deklaration übereinstimmt und die also_working()
-Funktion ergibt. Dort angekommen erkannte ich, dass ich aufgrund der Änderung des Umfangs im nachfolgenden Rückgabetyp auf eine Namensqualifizierung verzichten konnte, was die viel schönere working()
-Funktion ergab.
Nun frage ich mich, warum die Funktion not_working()
nicht funktioniert, dh warum ihre Definition nicht mit ihrer Deklaration übereinstimmt (ich könnte mich einfach mit der Lösung, die ich gefunden habe, nicht auskennen, aber ich werde wahrscheinlich mehr davon erfahren Probleme und ich möchte nicht mehr Zeit mit Versuch und Irrtum verschwenden); Liegt der Fehler innerhalb der Compiler oder in meinem Code? Ich habe 14.6 Namensauflösung [temp.res] gelesen, aber ich bin mir nicht sicher, welche Regeln für diesen Fall gelten.
Klärung der Frage : Gegeben die Regeln des C ++ 11 Standards:
not_working()
-Definition mit der Deklaration übereinstimmen? Es sieht so aus, als ob es versucht, CWG2 zu implementieren, aber möglicherweise Dinge in einer überraschenden Reihenfolge erledigt. Gcc-Fehler betrachten:
%Vor% Die Definition wird mit dem Rückgabetyp Dummy<bar<i>()>
angezeigt, die Kandidatendeklaration hat jedoch den Rückgabetyp Dummy<Foo<T>::bar<i>()>
. Insbesondere ist die Foo<T>::
Qualifikation für bar<i>
verloren gegangen.
Wenn wir die Definition von also_working
auf den Rückgabetyp Dummy<Foo<T>::template bar<2>()>
ändern, erhalten wir nützliche parallele Fehler:
Hier wird die Definition mit dem Rückgabetyp Dummy<Foo<T>::bar<2>()>
(wie geschrieben) angezeigt, und die Kandidatendeklaration hat den Rückgabetyp Dummy<Foo<T>::bar<i>()>
.
Offensichtlich unterscheidet sich Foo<T>::bar<i>
von bar<i>
auch im Kontext von Foo<T>
, da Foo<T>::template
weder in der Deklaration noch in der Definition des Rückgabetyps von also_working
entfernt wurde. lässt es aufhören zu arbeiten. (Wenn Sie beide herausnehmen, bekommen Sie working
zurück.)
Ich habe versucht, die Deklaration von not_working
zu ändern:
und jetzt klagt gcc:
%Vor% Was ziemlich unsinnig ist, da wir eine für den Charakter vergleichbare Deklaration und Definition Dummy<bar<i>()> Foo<T>::not_working()
haben, sobald der Compiler damit fertig ist.
Tags und Links c++11 templates language-lawyer trailing-return-type