"Mitglied ist privat", obwohl ich bei der Verwendung des abschließenden Rückgabetyps nicht von außen darauf zugreife

8

Wie kann ich das folgende Problem beheben?

Ich schreibe eine funktionale Bibliothek, die die folgenden Funktionen definiert, die für diese Frage relevant sind:

  • call(f,arg) : Ruft eine Funktion mit einem Argument auf. Nur ein Wrapper, den ich für einige Situationen brauche.
  • comp(f1,f2) : Gibt eine Zusammensetzung von zwei Funktionen zurück. Gibt einen Helfer-Funktor zurück, der die Zusammensetzung der beiden Funktionen darstellt.

Die Implementierung sieht wie folgt aus (vereinfachte Versionen, die das Problem noch zeigen):

%Vor%

Der folgende Code wird als einfacher Test verwendet:

%Vor%

Bis hier läuft alles gut. Der Aufruf von comp selbst scheint kein Problem zu sein. Der Aufruf der resultierenden Funktion ist ebenfalls in Ordnung. Wenn Sie jedoch die Komposition über call aufrufen, wird eine unendliche Anzahl von Kompilierungsfehlern (yaaay, new record!) Eingeführt:

%Vor%

Die Kompilierungsausgabe (gcc 4.7, volle Ausgabe siehe die folgenden ideone Links):

%Vor%

Beim Konvertieren der Komposition in std::function ist das auch völlig in Ordnung. Aber dies wird nicht erlauben, polymorphe Funktoren mit meiner Funktion comp zu verwenden, zumindest sehe ich keine Option.

Ein "Fix" ist es, nicht den abschließenden Rückgabetyp mit declltype für Comp::operator() zu verwenden, sondern den Rückgabetyp auf bool zu fixieren (spezialisiert auf dieses einzelne Testszenario).

Alle vier genannten Testfälle zusammengefasst:

  • Test1 - Rufen Sie die Komposition direkt auf - & gt; OK
  • Test2 - Rufen Sie die Komposition mit call - & gt; Fehler
  • Test3 - Übergeben Sie die Komposition an std :: function und rufen Sie dann mit call - & gt; OK
  • Test4 - Rufen Sie die Komposition mit call auf. Fester Rückgabetyp von Comp::operator() bis bool - & gt; OK

Mein Ziel besteht darin, call zu einem "nahtlosen" Wrapper zu machen, um einen beliebigen Funktionstyp aufzurufen: Funktoren, Funktionszeiger, Elementfunktionszeiger, Elementvariablenzeiger usw., und auch eine Komposition mit comp . Ich habe eine Reihe von Überladungen für sie, aber ich möchte keine Überladung für Comp<Fn1,Fn2> einführen, da Fn1 oder Fn2 wieder irgendeine Art von Funktion sein kann, es scheint ein "rekursives Problem" zu sein.

    
leemes 01.05.2013, 22:58
quelle

2 Antworten

2

Versuchen Sie, einen Ausdruck von Fn1 für a, Fn2 für b zu ersetzen, um die Erwähnung von privaten Mitgliedern zu vermeiden. Ich habe dies in VC ++ versucht, aber einen anderen Fehler bekommen:

%Vor%     
Scott Jones 01.05.2013, 23:21
quelle
6

Clang kompiliert Ihren fehlerhaften Testfall ganz gut und ich kann keinen Fehler damit sehen, also denke ich, dass dies ein GCC-Fehler ist. Bitte reichen Sie einen Fehlerbericht mit einer minimalen Repro (keine Includes), wenn Sie können.

Hinweis: Für call gibt es schon etwas wie es im Standard - INVOKE , das ist kein Makro, sondern sozusagen ein Konzept. Es wird von std::bind , std::function und anderen Dingen verwendet, von denen einer std::reference_wrapper ist. Das bedeutet, dass Sie std::ref(fun)(args...) ausführen können, um dasselbe wie call zu erreichen.

    
Xeo 01.05.2013 23:14
quelle