Perfect doorsturen in een lambda?

Perfect doorsturen in een lambda?

De canonieke manier om een ​​lambda-argument door te sturen dat was gebonden aan een doorstuurreferentie is inderdaad met decltype :

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

Mijn favoriete idioom hiervoor is:

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

die ik lees als "x als het type x is gedeclareerd als".

Om te zien hoe dit werkt, kijk wat er gebeurt als x is een int&& . decltype(x)(x) is (int&&)(x) , die een rvalue-verwijzing naar x . produceert . Als x is een int& , dan krijgen we (int&)(x) wat een noop is voor een verwijzing. Onthoud, decltype(x) bevat de referentiecategorie.

Nu, voor auto&& parameters dit is korter maar komt overeen met:

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

het alternatief.

Voor auto parameters:

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

het veroorzaakt een extra kopie, terwijl

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

in plaats daarvan beweegt-van x .

Hoewel ik casts in C-stijl meestal als te gevaarlijk beschouw, decltype(x)(x) kan in het slechtste geval een type-correcte kopie maken van x if x is geen auto&& variabel. En er valt iets te zeggen voor de beknoptheid ervan.