mardi 24 mai 2016

Getting size of a lambda callback signature? [duplicate]

This question already has an answer here:

I've been doing some reading regarding std::function which allows you to store functions, whether it be lambdas, std::bind expressions or any other callable targets.

Wrote this little 'class' with some help from google, but I can't seem to figure out how to get the size of a lambda callback signature? That's the main issue, but I also have a few other issues that need solving eg. when adding a new function, I have to specify function argument types twice - once in the template and once in a lambda. As well as not being able to return from the wrapper call() function, so I always have to pass parameters from the function by reference instead.

#include <map>
#include <memory>
#include <functional>
#include <iostream>

#define break_with_error(x) { std::cout << "ERROR: " << x << std::endl; return; }

struct functions_t {
    struct fn_t {
        virtual ~fn_t() = default;
    };

    template<typename ...A>
    struct cb_t : fn_t {
        using callback = std::function<void(A...)>;
        callback cb;

        cb_t(callback p_callback) : cb(p_callback) {}
    };

    template<typename ...A>
    void call(std::string name, A&& ... args)
    {
        if (!callbacks.count(name))
            break_with_error("[Function Call] Function with this name doesn't exist.");

        using Function = cb_t<A...>;
        using Callback = std::function<void(A...)>;

        const fn_t& Base = *callbacks[name];
        const Callback& Fn = static_cast<const Function&>(Base).cb;

        Fn(std::forward<A>(args)...);
    }

    template<typename ...Type, typename Function>
    void add(std::string name, Function lambda)
    {
        if (callbacks.count(name))
            break_with_error("[Function Add] Function with this name already exists.");

        using callback = cb_t<Type...>;
        callbacks[name] = std::unique_ptr<callback>(new callback(lambda));
    }

    void erase(std::string name)
    {
        if (!callbacks.count(name))
            break_with_error("[Function Remove] Function with this name doesn't exist.");

        auto it = callbacks.find(name);
        callbacks.erase(it);
    }

    void clear()
    {
        callbacks.clear();
    }

private:

    std::map<std::string, std::unique_ptr<fn_t>> callbacks;

};

void create_functions(functions_t *instance)
{
    instance->add<int, int, int&>("GetAnswer", [](int value1, int value2, int &sum)
    {
        sum = value1 + value2;
    });

    instance->add<int>("PostAnswer", [](int answer)
    {
        std::cout << "The ultimate answer to everything is " << answer << std::endl;
    });
}

int main()
{
    functions_t *fn_instance = new functions_t;
    create_functions(fn_instance);

    int answer;

    fn_instance->call("GetAnswer", 21, 21, answer);
    fn_instance->call("PostAnswer", answer);

    //Functions->erase("GetAnswer");
    //Functions->erase("PostAnswer");

    fn_instance->clear();

    delete fn_instance;
    getchar();

    return EXIT_SUCCESS;
}

Aucun commentaire:

Enregistrer un commentaire