2017-03-15 3 views
1

機能により、一つは書くことができます。ラムダでの完璧なフォワーディング?

template <class T> void f(T&& x) {myfunction(std::forward<T>(x));} 

をしかしラムダで、我々はTを持っていない:

auto f = [](auto&& x){myfunction(std::forward</*?*/>(x));} 

ラムダで完璧な転送を行うにはどのように? decltype(x)std::forwardの型として機能しますか?

答えて

4

フォワーディング参照にバインドされたラムダ引数を転送する標準的な方法は、decltypeで確かである。このため

auto f = [](auto&& x){ 
    myfunction(std::forward<decltype(x)>(x)); 
} //      ^^^^^^^^^^^ 
+1

コールオペレータテンプレートを使用してlambdaを作成する[C++ 2a](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0428r0.pdf)があります書きやすい。 –

+0

興味深いリンク。答えに直接リンクする価値はありませんか? – skypjack

+0

@skypjack:早期段階の提案の些細で投機的な性質、そしてC++ 14に関する問題であることを考えると、コメントとして残すのが一番良いと思いました。おそらく、これを受け入れるという実際の決定があったら、これを更新することができます(7月?)。 –

2

私のお気に入りのイディオムは次のとおりです。私は "として読み込ま

auto f = [](auto&& x){myfunction(decltype(x)(x));} 

xがタイプxとして宣言されました。

この動作を確認するには、xint&&の場合の処理​​を調べます。 decltype(x)(x)(int&&)(x)であり、これはxへの参照値を生成する。 xint&である場合は、(int&)(x)となります。これは参照へのキャストなしです。覚えておいてください、decltype(x)は参照カテゴリを含みます。

auto f = [](auto&& x){myfunction(std::forward<decltype(x)>(x));} 

代替:今

は、auto&&パラメータに対して、これは短いが、同等です。

auto f = [](auto x){myfunction(decltype(x)(x));} 

auto f = [](auto x){myfunction(std::forward<decltype(x)>(x));} 

代わり移動-からながらxそれは、余分なコピーを誘発:autoパラメータについて

私は通常のCスタイルがあまりにも危険であるとしてキャストxauto&&変数でない場合は、decltype(x)(x)は最悪のxの種類-正しいコピーを作成することができます扱いますが。そして、それを簡潔にするために何か言われることがあります。

+0

decltypeのキャストはきちんとしたトリックですが、私が 'std :: forward'について気に入っているのは、転送が進行中で、近くの' && 'が転送参照であるという(読んで欲しい)ヒントを作り出すということです。 –

+0

私はそれに同意します。簡潔さは意味の犠牲になります、IMO。ニースのトリック、+1! – Columbo

+0

コピーが作成された例を詳しく説明できますか? 'auto'パラメータの場合:... 'int a; 'auto x'が初期化されたとき(おそらく最適化されているとき)最初にコピーします. 最初の場合:' int(x) 'のためにコピーします) 2番目の場合:std :: forwardが 'int &&'にキャストされるため、移動(myFunctionがそのように実装されている場合)。あれは正しいですか? – Gabriel

関連する問題