Perfect forwaring of auto&& in generic lambda

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

Leave a Comment