Adrien Grosjean
Adrien Grosjean

Reputation: 63

C++ template lambda wrapper

Can anyone figure out how to make this compile ?

I'm trying to wrap a lambda in another function that does something (here printing "you know what") + calling the lambda.

Best would be to have automatic template parameters deduction.

#include <iostream>
#include <functional>
#include <utility>

void youKnowWhat(const std::function<void()>&& fun)
{
    std::cout << "You know what ?" << std::endl;
    fun();
}

template <typename... Args>
auto youKnowWhatSomething(const std::function<void(Args...)>&& fun)
{
    return [fun{std::move(fun)}](Args... args)
        {
            youKnowWhat(std::bind(fun, std::forward<Args>(args)...));
        };
}

int main()
{
    const auto imHavingSomething([](const std::string& s){
        std::cout << "Im having " << s << std::endl;
    });

    const auto youKnowWhatImHavingSomething(youKnowWhatSomething(std::move(imHavingSomething)));
    youKnowWhatImHavingSomething("fun with templates");
    youKnowWhatImHavingSomething("headaches");
}

Upvotes: 0

Views: 404

Answers (2)

Jarod42
Jarod42

Reputation: 217085

How about

#include <iostream>
#include <functional>
#include <utility>

template <typename F>
void youKnowWhat(F&& fun)
{
    std::cout << "You know what ?" << std::endl;
    fun();
}

template <typename F>
auto youKnowWhatSomething(F&& fun)
{
    return [fun{std::move(fun)}](auto&&... args) -> decltype(fun(std::forward<decltype(args)>(args)...), void())
        {
            youKnowWhat([&](){fun(std::forward<decltype(args)>(args)...); });
        };
}

int main()
{
    const auto imHavingSomething([](std::string s){
        std::cout << "Im having " << s << std::endl;
    });

    const auto youKnowWhatImHavingSomething(youKnowWhatSomething(imHavingSomething));
    youKnowWhatImHavingSomething("fun with templates");
    youKnowWhatImHavingSomething("headaches");
}

Demo

Upvotes: 1

Llu&#237;s Alemany-Puig
Llu&#237;s Alemany-Puig

Reputation: 1188

Will this work for you? I've (basically) removed the const from const ... &&, and added a template parameter to the function youKnowWhatSomething. The lambda is no longer declared as const in main.

#include <iostream>
#include <functional>
#include <utility>

void youKnowWhat(const std::function<void()>& fun)
{
    std::cout << "You know what ?" << std::endl;
    fun();
}

template<typename function_t, typename... Args>
auto youKnowWhatSomething(function_t&& fun)
{
    return [fun{std::move(fun)}](Args... args)
        {
            youKnowWhat(std::bind(fun, std::forward<Args>(args)...));
        };
}

int main() {
    auto imHavingSomething = [](std::string s) {
        std::cout << "Im having " << s << std::endl;
    };

    const auto youKnowWhatImHavingSomething =
        youKnowWhatSomething<decltype(imHavingSomething), std::string>
        (std::move(imHavingSomething));

    youKnowWhatImHavingSomething("fun with templates");
    youKnowWhatImHavingSomething("headaches");
}

Upvotes: 1

Related Questions