2016-07-06 6 views
0

引数(パラメータパック)を格納し、引数を別の関数に渡す必要があります。
その結果、私はラムダを使用できません。そして良い選択はstd :: bindです。

しかし、このコードの完全な転送を伴うstd :: bind call operator()

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 
} 

STDに保存されている標準、すべての変数による::バインドが機能するために左辺値として渡されます。 (C++標準では、そのことを意味するとは思わない)
これは、std :: bindで関数(rvalue参照をパラメータに持つ)を使用できないことを意味します。

test(A &&)test(A &)に変更する方法がありますが、これはプロジェクトでのみ有効です(std :: threadでテストを呼び出す必要があるだけでなく、通常の順次呼び出しでテストを呼び出す必要があります)。

この問題を解決する方法はありますか?

+4

*「ラムダは使用できません」*、それについて詳しく説明できますか?あなたが言及しているパラメータパックはどこですか? –

+0

@NathanOliverあなたは 'foo'を呼び出すのを忘れました –

+0

@PiotrSkotnicki良い点。私はそれをし、それは驚くほど失敗する。 – NathanOliver

答えて

1

あなたは右辺値参照に変換されるラッパーを作成します(のようなreference_wrapper/L値参照)とbindでそれを使用することができます。

それはそのように見えるCAL:

#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

注:rvalue_holderと特にrvalの両方は、すべての場合で効率、堅牢性および望ましい動作を保証するためにさらに作業が必要です。

+0

しかし、私はこの解決法を使用しないかもしれません。ありがとう。 – Caesar

関連する問題