2016-07-06 8 views
0

Ich muss Argumente (Parameter Pack) speichern und die Argumente an eine andere Funktion übergeben.
Als Ergebnis kann ich Lambda nicht verwenden. Und eine gute Wahl ist std :: bind.

Aber für diesen CodeC++ - std :: binden Aufrufoperator() mit perfekter Weiterleitung

struct A{}; 

void test(A &&){} 

int main() 
{ 
    A a; 
    test(move(a)); //work 
    bind(test,a)(); //compile fail; copy a to std::bind, pass a to test 
} 

Laut Norm, alle in std :: bind gespeicherten Variablen als L-Wert übergeben werden, funktionieren. (Der C++ - Standard sagt das nicht, indem ich denke, dass es das ist.)
Und das bedeutet, dass ich eine Funktion (hat Rvalue-Verweis in Parameter) mit Std :: Bind nicht verwenden kann.

Eine Lösung ist test(A &&) zu test(A &) zu ändern, aber das funktioniert nur für Ihr Projekt (und es seltsam, während Sie nicht nur Test von std :: Thread aufrufen müssen, sondern auch Test durch Klar sequentielle Aufruf aufrufen müssen).

Gibt es also Möglichkeiten, dieses Problem zu lösen?

+4

* "Ich kann Lambda nicht benutzen" *, können Sie das näher erläutern? und wo ist das Parameterpaket, das du erwähnst? –

+0

@NathanOliver Sie vergaßen, 'foo' zu nennen –

+0

@PiotrSkotnicki Guter Punkt. Ich habe das gemacht und es scheitert spektakulär. – NathanOliver

Antwort

1

Sie Wrapper erstellen können, die auf die rvalue Referenz konvertierbar sein wird (wie reference_wrapper/l-Wert-Referenzen) und verwenden Sie es mit bind:

Es sieht cal wie folgt aus:

#include <iostream> 
#include <functional> 

struct A{}; 

void test(A &&){ std::cout << "Works!\n"; } 

template <typename T> 
struct rvalue_holder 
{ 
    T value; 
    explicit rvalue_holder(T&& arg): value(arg) {} 
    operator T&&() 
    { 
     return std::move(value); 
    } 
}; 

template <typename T> 
rvalue_holder<T> rval(T && val) 
{ 
    return rvalue_holder<T>(std::move(val)); 
} 

int main() 
{ 
    A a; 
    test(std::move(a)); //work 
    auto foo = std::bind(test, rval(std::move(a))); //works 
    foo(); 
} 

http://coliru.stacked-crooked.com/a/56220bc89a32c860

Hinweis: Sowohl rvalue_holder als auch speziell rval erfordern weitere Arbeiten, um in allen Fällen die Effizienz, Robustheit und das gewünschte Verhalten sicherzustellen.

+0

Großartig. Aber ich kann diese Lösung nicht verwenden. Vielen Dank. – Caesar