2012-04-07 15 views
5

ich folgende glauben eine billigste Art der Bindung lokale Variable Schließung sein:Günstigste Weise lokale Variable Schließung der Bindung

void ByRValueReference(A&& a) { 
} 

std::function<void()> CreateClosureByRValueReference() { 
    A a; 
    std::function<void()> f = std::bind(&ByRValueReference, std::move(a)); // !!! 
    return f; 
} 

Es ist jedoch nicht kompiliert unter Clang 3.1:

error: no viable conversion from '__bind<void (*)(A &&), A>' to 'std::function<void()>' 

und gcc 4.6.1:

/usr/include/c++/4.6/functional:1778:2: error: no match for call to ‘(std::_Bind<void (*(A))(A&&)>)()’ 

Verstehe ich den Standard oder es ist nur gebrochene Standardbibliotheken?

+1

Ich denke, seine Funktion '. – RedX

+2

Was hier eigentlich etwas teuer ist, ist 'std :: function'. Wenn Sie wirklich auf Effizienz achten, würde ich 'declltype (std :: bind (...)) zurückgeben' – pmr

Antwort

3

Dies ist ein Design von std::bind. Die vollständige Spezifikation ist in 20.8.9.1.2 Funktions Vorlage binden [func.bind.bind], aber in diesem Fall ist die letzte Kugel des Absatzes 10 (das beschreibt, wie die gebundenen Parameter verwendet werden) gilt:

- sonst Vi, ist der Wert tid und seine Art ist TiD cv &

also in anderen Worten, std::move(a) in dem Anruf wrapper führen eine A (von move Bau) speichert, und dann, wenn operator() dieses Element verwendet wird, wird weitergeleitet als ein Wert (mit zusätzlichen cv-Qualifier passen zu den cv-Qualifiern des Call Wrappers, aber ich schweife ab). Obwohl es als rvalue bestanden wurde.

kann argumentiert werden, Diese
std::bind([](A& a) { ByRValueReference(std::move(a)); }, std::move(a)) 

, dass es eingewickelt, dass weitere Anrufe fragwürdig sind zu dem resultierenden Anruf deutlicher ist (da das A Mitglied zu haben, haftet gewesen:

Diese Art von Mismatch kann über eine Lambda gelöst werden bewegt), aber ich bin nicht übermäßig gern das Verhalten von std::bind als Ganzes.

+0

Wenn Sie mit einem Lambda gehen, können Sie auch '[& a]() {...}' zurückgeben direkt und speichern Sie sich die Bindung ... –

+0

@KerrekSB Dies hat andere Semantik als der Aufruf an 'std :: bind' und im OP-Fall wird zu UB führen. –

+0

Oh, ich sehe tatsächlich. Vielen Dank. –

Verwandte Themen