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