std::function<> und Rvalue-Referenzen
-
Hallo!
Mit Google konnte ich leider nicht viel außer einen VS-Bug finden, der sich auf das Problem beziehen könnte, es geht um Rvalue-Referenzen in std::function<>-Objeken:#include <function> #include <iostream> void test(int&& i, char c) { std::cout << i; } int main() { std::function<void (int&&, char)> f(test); auto function = std::bind(f, std::placeholders::_1, 'A'); function(5); }So rein theoretisch/semantisch müsste das doch eigentlich funktionieren, tut's aber nicht. Irgendwo in den Tiefen der Fehlermeldungen von std::function finde ich:
error C2664: 'void std::tr1::_Function_impl2<_Ret,_Arg0,_Arg1>::operator ()(_Arg0,_Arg1) const': Konvertierung des Parameters 1 von 'int' in 'int &&' nicht möglich Ein lvalue kann nicht an einen rvalue-Verweis gebunden werden.Was ist falsch?
-
Scheint so, als ob die Mitarbeiter Microsofts bei der Implementierung von std::function ein paar mal std::forward vergessen haben. Die "rvalue-ness" der 5 müsste eigentlich durchgehend erhalten bleiben. Müsste in diesem konkreten Fall etwa so aussehen (pseudo code):
class function<void(int&&,char)> { .... void operator()(int&& a, char b) const { return abc_ptr->invoke(std::forward<int&&>(a), std::forward<char>(b)); } .... unspezifizierter-typ *abc_ptr; };wobei über abc_ptr das gewrappte Funktionsobjekt erreichbar ist. So etwas ähnliches müsste dann auch in der invoke-Funktion gemacht werden.
-
Das heißt, ich kann function nicht benutzen. Ich brauche es aber (wegen bind). Und Rvalue-Referenzen brauche ich auch, da der Typ definitiv nicht kopierbar sein soll. Was kann ich jetzt machen?
-
Das ist der Nachteil wenn man experimentelle Features nutzt. Auf ein Update der Dinkumware-Bibliothek warten wäre wohl die beste Möglichkeit ...
-
Und wenn du ja schon C++0x nutzt, könntest du ja auch gerade
decltypenutzen:void test(int&& i, char c) { std::cout << i; } int main() { std::function<decltype(test)> f(test); auto function = std::bind(f, std::placeholders::_1, 'A'); function(5); }
-
Jodocus schrieb:
Und Rvalue-Referenzen brauche ich auch, da der Typ definitiv nicht kopierbar sein soll. Was kann ich jetzt machen?
Wie hättest du es in C++98 gelöst?
Referenzen und
swap()sind eine Möglichkeit, Smart-Pointer eine andere. Zeig mal etwas konkreten Code.
-
> Wie hättest du es in C++98 gelöst?
Die Frage habe ich mir auch gestellt und kam auf Smart-Pointer. Aber ideal finde ich es nicht.
Meine dreckige Idee: ich mache es wie std::auto_ptr. Der Kopierkonstruktor der Resourcenklasse ist private - logisch. Was nun, wenn ich std::function<> in der Klasse als Friend deklariere? Geht das? Darf man das? Denn dann könnte ich den Kopierkonstruktor wie bei auto_ptr move-Eigenschaften geben und auf Rvalue-Referenzen verzichten.
@ EOutofRessources: Was bringt mir decltype() da? Das ist doch unterm Strich der selbe Typ - die selbe Fehlermeldung.