Ich versuche, den folgenden Code funktionieren zu lassen:
%Vor%Der Aufruf von f () an Foo :: f2 (der letzte Parameter ist ein roher Zeiger) funktioniert gut, aber die Bindung an foo :: f1 verursacht einen Kompilierungsfehler:
%Vor%Was mache ich falsch?
Ich verwende gcc 4.8.2 und -std = c ++ 0x (-std = c ++ 11 scheitert auch) flags.
Danke
Die Probleme mit Bind, die in den anderen Antworten beschrieben werden (zum Zeitpunkt des Schreibens), sind nicht das, worüber sich der Compiler in der Frage beschwert. Das Problem ist, dass std::function
CopyConstructible sein muss, was erfordert, dass sein Argument (das von der Funktion gespeichert wird) auch CopyConstructible ist.
Aus der Standardfunktion [20.9.11.2 Klassenvorlage]
%Vor%Benötigt: F soll CopyConstructible sein. f soll Callable (20.9.11.2) für Argumenttypen ArgTypes und Rückgabetyp R sein. Der Kopierkonstruktor und der Destruktor von A dürfen keine Ausnahmen auslösen ...
Betrachten Sie dieses Beispiel, in dem nicht einmal bind enthalten ist:
%Vor%Hier ist die Ausgabe von clang:
%Vor%Beachten Sie, dass das resultierende Bindeobjekt nicht kopierbar ist, wenn Sie ein unique_ptr binden. Bind wird trotzdem noch kompiliert.
Hmm, es scheint wirklich, dass std :: bind Probleme mit r-Wert-Referenzen hat. Eine Alternative wäre die Verwendung einer Lambda-Funktion:
%Vor%Damit dies funktioniert, müssen Sie auch die Signatur von f1 so ändern, dass sie unique_ptr als r-Wert-Referenz akzeptiert:
%Vor%(Auch wenn std :: bind R-Wert-Referenzen verarbeiten könnte, müssten Sie dies trotzdem tun, weil std :: unique_ptr keinen Kopierkonstruktor hat, nur der Move-Konstruktor ist zugänglich!)
Beachten Sie jedoch, dass Ihr Konstrukt ziemlich gefährlich ist (auch wenn std :: bind funktionieren würde): Wenn Sie f () zweimal aufrufen, erhalten Sie eine Laufzeitausnahme.
1) Der folgende Code wird nicht kompiliert
%Vor% weil function
erfordert, dass das Callable-Objekt copy-constructible ist, aber wenn bind
ein nicht kopierbares Argument wie unique_ptr
benötigt, wird der zurückgegebene Funktor nicht kopierbar sein, wie in anderen Antworten erwähnt.
2) Verwenden Sie also nicht function
für bind
. Der folgende Code wird jedoch nicht kompiliert
weil in Schritt (a) bind
speichert, was Sie ihm als lvalue geben (außer für reference_wrapper
), und es an den internen Funktor in Schritt (b) übergibt. Daher ist es erforderlich, dass die gebundenen Argumente kopierbar sind, denn diese Parameter werden nach Wert übergeben, nicht nach Referenzen.
3) Versuchen Sie dann, den rohen Zeiger zu verwenden. Der folgende Code wird jedoch nicht kompiliert
%Vor% Ein ähnlicher Grund wie (2), der Funktor speichert ein int*
und versucht, es beim Aufruf in den Parametertyp unique_ptr<int>
zu konvertieren. Aber der Konstruktor unique_ptr(pointer p)
ist explicit
.
Um es zu kompilieren, benötigen Sie eine Funktion wie diese
%Vor% Beachten Sie, dass f
mehrmals aufgerufen werden kann und die Parameter p
auf dasselbe unique_ptr
verweisen, das im zurückgegebenen Objekt von bind
gespeichert ist.