2017-03-15 64 views
1

與函數,可以寫成:在lambda中完美轉發?

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

有一個[C++ 2a的建議](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0428r0.pdf)使用調用操作符模板創建lambdas寫起來容易一點。 –

+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)這是一個noop投給參考。請記住,decltype(x)包含參考類別。

現在,對於auto&&參數這是較短,但等效於:

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

雖然我通常把C-風格轉換爲太危險了,decltype(x)(x)可以在最壞的情況做的一個x類型正確的副本,如果x不是auto&&變量。有一點可以說是簡潔的。

+0

decltype轉換是一個巧妙的技巧,但我喜歡'std :: forward'的是它創建了一個可讀的(並且可以greppable)的提示,轉發正在進行,並且附近的一個'&&'是轉發引用。 –

+0

我同意那個;簡潔是以意義爲代價的,IMO。不錯的技巧,+1! – Columbo

+0

您能否詳細說明覆制的實例?對於'auto'參數:... 'int a; f(a);' - >'auto == int',當'auto x'被初始化時可能首先被複制(可能被優化), 然後在第一種情況下:複製因爲int(x)' ) 在第二種情況下:移動(如果myFunction是這樣實現的),因爲std :: forward轉換爲int &&。那是對的嗎? – Gabriel