與函數,可以寫成:在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
的類型嗎?
與函數,可以寫成:在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
的類型嗎?
的規範方式來轉發被綁定到轉發參考拉姆達的說法的確是有decltype
:
auto f = [](auto&& x){
myfunction(std::forward<decltype(x)>(x));
} // ^^^^^^^^^^^
我給這家最喜歡的成語是:
auto f = [](auto&& x){myfunction(decltype(x)(x));}
我讀作「 x
作爲x
類型被聲明爲「。
要了解其工作原理,請檢查x
是int&&
時會發生什麼情況。 decltype(x)(x)
是(int&&)(x)
,它產生一個參考x
的右值。如果x
是int&
,那麼我們得到(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&&
變量。有一點可以說是簡潔的。
decltype轉換是一個巧妙的技巧,但我喜歡'std :: forward'的是它創建了一個可讀的(並且可以greppable)的提示,轉發正在進行,並且附近的一個'&&'是轉發引用。 –
我同意那個;簡潔是以意義爲代價的,IMO。不錯的技巧,+1! – Columbo
您能否詳細說明覆制的實例?對於'auto'參數:... 'int a; f(a);' - >'auto == int',當'auto x'被初始化時可能首先被複制(可能被優化), 然後在第一種情況下:複製因爲int(x)' ) 在第二種情況下:移動(如果myFunction是這樣實現的),因爲std :: forward轉換爲int &&。那是對的嗎? – Gabriel
有一個[C++ 2a的建議](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0428r0.pdf)使用調用操作符模板創建lambdas寫起來容易一點。 –
有趣的鏈接。將鏈接直接放在答案中是否值得? – skypjack
@skypjack:鑑於早期階段提案的細微和推測性,以及事實上這個問題是關於C++ 14的,我認爲最好留下來作爲評論。也許一旦有實際的決定接受這個,我們可以更新這個(7月?)。 –