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:
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, Comp::operator()
zu verwenden, sondern den Rückgabetyp auf bool
zu fixieren (spezialisiert auf dieses einzelne Testszenario).
Alle vier genannten Testfälle zusammengefasst:
call
- & gt; Fehler
call
- & gt; OK 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.
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%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.
Tags und Links c++ c++11 functional-programming templates metaprogramming