2017-05-12 3 views
0

Ich versuche, ein Callable-Objekt zu machen, das im Wesentlichen eine gebundene unique_ptr enthält. Ich habe gelesen How to capture a unique_ptr into a lambda expression?Ist es möglich, ein Lambda mit einem nicht kopierbaren (verschobenen) Wert zu übergeben?

Aber ich kann das Lambda nicht weiter bestehen. Der folgende Code kann nicht kompiliert werden, was darauf hinweist, dass das Kopieren unique_ptr stattfindet. Ich verstehe nicht ganz, warum es versuchen würde, die unique_ptr zu kopieren.

#include <iostream> 
#include <memory> 
#include <functional> 

using namespace std; 

void f(std::function<void(int)> unary) { 
    unary(42); 
    unary(1337); 
} 

struct A{ 
    void woof(int i) {cout<< "woof " << i << "\n";} 
}; 

int main(){ 
    auto another_unique = make_unique<A>(); 
    auto bound_p = [ p = move(another_unique) ] (int i) {p->woof(i);}; 
    bound_p(5); 
    f(bound_p); // does not compute 
} 

ich auch habe versucht, Lambda-inline im Aufruf f definieren, so dass es ein temporäres Objekt sein würde, und es könnte in f bewegt werden. Aber der Fehler war der gleiche.

Ist es möglich, ein solches Objekt in Callables einzubinden und diese weiterzugeben?

Mein Anwendungsfall hängt unique_ptr, aber ich vermute, dass jedes Objekt mit gelöschten Kopie c'tor das gleiche Problem aufweisen wird. Wenn ich falsch liege, dann sag mir bitte oder bearbeite das Thema, um weniger allgemein zu sein.

Antwort

4

Sie können keine move-only Typ std::function eingeben. Für diese Klasse muss der Typ kopierbar sein.

Ein besserer Weg, um dies zu behandeln wäre f eine Vorlage, die den angegebenen Parameter aufrufen wird, anstatt den Typ gelöscht std::function verwenden. function sollte für Fälle verwendet werden, in denen Sie behalten möchten eine Kopie des Funktors herum, nicht wenn Sie es nur anrufen möchten.

+0

'unary' soll ein Rückruf sein, also würde ich etwas brauchen, das ich speichern und dann anrufen kann. 'f' ist ein Mock zum Aufruf eines gespeicherten Callable. – luk32

+0

@ luk32: Nun, es gibt keine reine Version von 'std :: function'. Sie haben also die Möglichkeit, den Nur-Bewegungstyp aus Ihrem Lambda zu entfernen. Oder schreiben Sie Ihr eigenes Äquivalent zur 'std :: function'. –

+0

Eine 'view_function' hat eine bessere Bedeutung als die einfache Vorlage BTW. Traurig, dass 'std :: function' dafür verwendet wird. – Jarod42

Verwandte Themen