Out-of-Line-Elementvorlagenfunktionsdefinition unter Verwendung einer anderen Elementvorlagenfunktion in der Signatur

9

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:

  1. Soll die not_working() -Definition mit der Deklaration übereinstimmen?
  2. welche Regeln sind an der Bestimmung von 1 beteiligt?
  3. Wie interagieren die Regeln von 2. bei der Bestimmung von 1.?
psyill 14.03.2017, 10:52
quelle

1 Antwort

0

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:

%Vor%

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:

%Vor%

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.

    
TBBle 10.05.2017 16:58
quelle