In C++20 and later
auto lambda20 = []<class F, class...Ts>(F &&fn, Ts &&...args) {
return std::forward<F>(fn)(std::forward<Ts>(args)...);
};
In C++pre20 : C++11,14,17
auto lambda14 = [](auto &&fn, auto &&...args) {
return std::forward<
std::conditional_t<
std::is_rvalue_reference_v<decltype(fn)>,
typename std::remove_reference_t<decltype(fn)>,
decltype(fn)>
>(fn)(
std::forward<
std::conditional_t<std::is_rvalue_reference<decltype(args)>::value,
typename std::remove_reference<decltype(args)>::type,
decltype(args)
>>(args)...);
};
Example
#include <iostream>
using namespace std;
int main() {
auto lambda20 = []<class F, class...Ts>(F &&fn, Ts &&...args) {
return std::forward<F>(fn)(std::forward<Ts>(args)...);
};
auto lambda14 = [](auto &&fn, auto &&...args) {
return std::forward<
std::conditional_t<
std::is_rvalue_reference_v<decltype(fn)>,
typename std::remove_reference_t<decltype(fn)>,
decltype(fn)>
>(fn)(
std::forward<
std::conditional_t<std::is_rvalue_reference<decltype(args)>::value,
typename std::remove_reference<decltype(args)>::type,
decltype(args)
>>(args)...);
};
int inter = 20;
lambda20([](int x) { cout << "asdf20 x" << endl; }, inter);
lambda20([](int &x) { cout << "asdf20 &x" << endl; }, inter);
lambda20([](int &&x) { cout << "asdf20 &&x" << endl; }, std::move(inter));
lambda14([](int x) { cout << "asdf14 x" << endl; }, inter);
lambda14([](int &x) { cout << "asdf14 &x" << endl; }, inter);
lambda14([](int &&x) { cout << "asdf14 &&x" << endl; }, std::move(inter));
return 0;
}
C++ pre-20 solution 8 years old by Scott Meyers https://scottmeyers.blogspot.com/2013/05/c14-lambdas-and-perfect-forwarding.html
solved Perfect forwaring of auto&& in generic lambda