Simple module system (callbacks) - c++

I'm trying to make a simple module engine, but I don't really know where to start, I want to create something like this:
int awesomefunction() {
// do something here
execute_awesomefunction_callbacks_here();
// some more stuff
}
The *execute_awesomefunction_callbacks_here();* would execute all the functions that are in a std::vector
Any ideas on how to achieve this? Or are there any better ways of doing this?

You could implement it with an std::vector of std::function. The only constraint is that all the function objects must have compatible return type and argument types.
class Publisher {
public:
void registerSubscriber(std::function<int(int, double)> callback) {
callbacks_.push_back(callback);
int executeAwesomeFunction() const {
// loop over vector calling each function object.
}
private:
std::vector<std::function<double(int,double)>> callbacks_;
}
This requires C++11 support, but you can achieve the same using boost::function

Related

Can the same generic function receive a pointer to both a member-function and a regular-function as a single argument?

I currently have 2 nearly-identical (functionality-wise) functions:
class MyClass
{
public:
void CallFunc(auto fncPtr)
{
fncPtr();
}
void CallMemFunc(auto (MyClass::*fncPtr)())
{
(this->*fncPtr)();
}
};
Is there any way to combine both generic functions into a single generic function?
Either by somehow generalizing the function's parameter further, or by adding both as separate parameters (with some default values) to the function?
To clarify, the above functions serve as a simple example to what I'm trying to achieve - My code has 2 functions with near-identical functionality that differ only by the fact that one of them handles a pointer-to-member-function while the other handles a pointer-to-general-function, like in the above case (though my issue isn't with the above functions per-se).
Not sure it is what you want and if it is better than simple overload, but you can do:
void Call(auto func)
{
if constexpr (std::is_invocable_v<decltype(func)>) {
std::invoke(func);
} else if constexpr (std::is_invocable_v<decltype(func), MyClass*>) {
std::invoke(func, this);
}
}
Demo

boost member function pointers

I am very new to the boost libraries.
I was trying to accomplish something for a graphical program, by binding the callbacks passed
to glutDisplayFunc(), etc to a single class.
I wanted to accomplish this without having some constant global class object.
To explain in code:
class CallbackHolder {
public:
void dostuff(void) {
// etc.
}
};
void bind() {
glutIdleFunc((new CallbackHolder())->dostuff);
}
I know this is possible through the usage of boost::bind and boost::function.
One issue I did see however was converting the boost::function back to a normal function pointer.
How would you accomplish this?
You can't convert from boost::function to a normal function pointer, and you can't convert from a member function pointer to a normal function pointer. There are workarounds for functions accepting callback where you can provide user data.
Unfortunately the glut interface doesn't let you provide user data. This means you're stuck with the ugliest solution, using a global variable and a normal function.
class CallbackHolder {
public:
void dostuff(void) {
// etc.
}
};
CallbackHolder * g_callbackHolder = NULL;
void call_callback_holder(void) {
if(g_callbackHolder) g_callbackHolder->dostuff();
}
void bind() {
g_callbackHolder = new CallbackHolder();
glutIdleFunc( &call_callback_holder );
}

C++ Function pointers vs Subclasses

I am in a position to choose between function pointers and subclassed objects. To make it clear, say I have to notify some object of some action (a timer for example); refer to the following two choices (a very basic code for demo purposes):
Version 1
typedef void TimerCallback(void *args);
class Timer{
public:
Timer();
~Timer();
void schedule(TimerCallback *callback, void *args, long timeout)=0;
void cancel();
};
Version 2
class TimerTask{
public:
TimerTask();
virtual ~TimerTask();
void timedout()=0;
};
class Timer{
public:
Timer();
virtual ~Timer();
void schedule(TimerTask *callback, long timeout)=0;
void cancel();
};
which one is the standard C++ way and which one is efficient? Please let me know if you have any other suggestions in this regard.
Please let me know if I am not clear in this regard.
Thanks
I would say std::function and std::bind. Then it doesn't matter if you want to use inherited classes, standalone functions, member functions or lambdas.
By the way, if anyone is curious I made a simple timer event handling some time ago, as an answer to another question. It's showcasing the use of e.g. std::function and std::bind: https://stackoverflow.com/a/11866539/440558.
I think it's better to use boost(or std since C++11)::function to hold callback and boost::bind to bind it's arguments, or to use boost::signal.
That would be more general and verbose solution at cost of really small penalty.
http://www.boost.org/doc/libs/1_53_0/doc/html/signals2.html
You are using object-oriented programming and you should follow the object-oriented programming paradigms.
In my opinion using objects, not function pointers, is the cleaner and generally better way to do.
You can also attempt to use a visitor pattern to make the code even better and more flexible.
You can also consider publisher/subscriber pattern.
Function pointer effectively prevents you to use closures - assigning methods to you event handler (This is not entirely true, but it will restrict you in such way, that this solution is not much of a use).
I would vote on object-oriented approach. If you use C++11, you may simplify your code a lot:
#include <cstdio>
#include <functional>
class Emitter
{
private:
std::function<void(int)> eventHandler;
public:
void SetEventHandler(std::function<void(int)> newEventHandler)
{
eventHandler = newEventHandler;
}
void EmitEvent()
{
eventHandler(42); // + error-checking
}
};
class Handler
{
private:
void HandleEvent(int i)
{
printf("Event handled with i == %d\n", i);
}
public:
void AttachEmitter(Emitter & e)
{
e.SetEventHandler([this](int i) { HandleEvent(i); });
}
};
int main(int argc, char * argv[])
{
Emitter e;
Handler h;
h.AttachEmitter(e);
e.EmitEvent();
}
Both work. Your first one is "C style" and will require a static function somewhere. The second version is "C++ style" and allows you to use an instance of TimerTask.
Generally, version 2 should be used because it removes the need for a static function.

map of pointers to functions of different return types and signatures

I am looking for a way to call different functions by a string input.
I have a map that ties each unique string to a function pointer and a lookup function to search the map and return a pointer if found.
Now the trick is, I need a way to store and return pointers to functions with at least different return types, if possible, also with different signatures.
The usage would be:
Get a string input from a network socket ->
find and execute the found function -> shove the result straight back into the socket to be serialized and sent, not caring what actually happened.
Is this doable? If not, how would one approach this task?
That can be done with a bit of boilerplate code in different ways. If the number of signatures is small enough you can hold multiple vectors of function pointers (one per function type) and then a map that maps the function name with a type identifier (used to select the vector) and the position within the vector.
The second option would be to store a boost::variant (again, if the set of signatures is small). You would need to provide a visitor object that evaluates the function (for each function type stored) and yields the result. The type is managed by the boost::variant type so there would be no need for the type tag to be stored in the map.
You can also use full type erasure and store in the map a tag determining the type of function to be called and a boost::any object storing the function pointer. You can use the type information to retrieve the pointer and execute the function, but you will have to manually handle the switch based on function type.
The simplest approach, on the other hand, is to write adapters that have a fixed interface. Then just store the pointers to the adapters in the map.
While you can't store different function pointers, you can store objects which contain those functions.
#include <iostream>
#include <cmath>
#include <map>
#include <string>
using namespace std;
class Functor{
public:
template<class T>
void operator()(T data){}
};
template<class T>
class BaseFunctor : public Functor{
public:
virtual void CallFunction(T data){ }
};
class FunctionPointer1 : public BaseFunctor<void *>{
public:
void doFunction1(){
cout << "Do Function 1"<<endl;
}
template<class T>
void CallFunction(T data){ doFunction1(); }
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPointer2 : public BaseFunctor<int>{
public:
void doFunction2(int variable){ cout << "Do function 2 with integer variable" << variable <<endl; }
template<class T>
void CallFunction(T data) { doFunction2(data);}
template<class T>
void operator()(T data){ this->CallFunction(data); }
};
class FunctionPerformer{
private:
map<string,Functor> functions;
public:
FunctionPerformer(){
//init your map.
FunctionPointer1 function1;
FunctionPointer2 function2;
//-- follows
functions["Function1"] = function1;
functions["Functions2"] = function2;
//-- follows
}
Functor getFunctionFromString(string str){
return functions[str]
}
};
int main(int argc, char *argv[])
{
map<string,Functor> functions;
FunctionPerformer performer;
Functor func1, func2; // to hold return values from perfomer()
FunctionPointer1 *fn1; // to casting and execute the functions
FunctionPointer2 *fn2; // to casting and execute the functions
func1 = performer.getFunctionFromString("Function1");//get data
func2 = performer.getFunctionFromString("Function2");
//following two lines to cast the object and run the methods
fn1 = reinterpret_cast<FunctionPointer1 *>(&func1);
(*fn1)(NULL);
//following two lines to cast the object and run the methods
fn2 = reinterpret_cast<FunctionPointer2 *>(&func2);
(*fn2)(10);
system("Pause");
return 0;
}
I think the edited part makes it clearer?
This code can be optimized a little. Play around with it.
This is doable in C++11 with Variadic Templates. Check my answer at https://stackoverflow.com/a/33837343/1496826
No, it's really not doable, you need a real interpreted language if you want to do something like this. As soon as the signature is not constant then you need something a lot more involved.
How about making all those functions have the same signature? You could make all return types implement an interface, or use a collection, class, union or struct. Same for the arguments.
Can't you use specialization and templates to work around the issue?
template <class T>
T FooBar(void * params);
template<> int FooBar<int>( void * params );
template<> char FooBar<char>( void * params );
Instead of storing the function pointers themselves, which are too different from one another to be accommodated into the same data structure, you can store adaptors that take care of bridging the mismatch. This is a form of type-erasure. An example:
// Imaginary important resources
blaz_type get_blaz();
qux_type get_qux();
// The functions we'd like to put in our map
int foo(blaz_type);
std::string bar(qux_type);
using context_type = std::tuple<blaz_type, qux_type>;
using callback_type = std::function<void(context_type, socket_type&)>;
using std::get;
std::map<std::string, callback_type> callbacks = {
{
"foo"
, [](context_type context, socket_type& out)
{ marshall(out, foo(get<0>(std::move(context)))); }
}
, {
"bar"
, [](context_type context, socket_type& out)
{ marshall(out, bar(get<1>(std::move(context)))); }
}
};
In this example the adaptors are not stateful so you can actually use void (*)(context_type, socket_type&) as the callback_type.
Do note that this kind of design is a bit brittle in that the context_type needs to know about every kind of parameter a stored callback might ever need. If at some later point you need to store a callback which needs a new kind of parameter, you need to modify context_type -- if you improve the above design not to use magic numbers like 0 and 1 as parameters to std::get you could save yourself some pains (especially in the reverse situation of removing types from context_type). This is not an issue if all callbacks take the same parameters, in which case you can dispense yourself with the context_type altogether and pass those parameters to the callbacks directly.
Demonstration on LWS.

Specify an inline callback function as an argument

Let me first explain what I'm trying to achieve using some pseudo-code (JavaScript).
// Declare our function that takes a callback as as an argument, and calls the callback with true.
B(func) { func(true); }
// Call the function
B(function(bool success) { /* code that uses success */ });
I hope this says it all. If not, please comment on my question so I can write a little more to clarify my issue.
What I want is to have code like this in C++.
I have tried to use lambda functions, but I was unable to specify a parameter type for those.
If your compiler is a fairly recent release (such as Visual Studio 2010 or GCC 4.5), you can use some new features from the new C++ standard, which is currently in ratification and should be published soon.
I don't know what you need to do to enable this in Visual Studio, but it should be well-documented either on MSDN or internal help.
For GCC 4.5, just add the -std=c++0x option to enable the new features.
One of these features is the Lambda syntax:
template <typename F>
void func_with_callback(F f) {
f(true);
}
int main() {
func_with_callback( [](bool t){ if(t) cout << "lambda called" << endl; } );
}
If you don't have access to a modern compiler, you can use techniques such as functors and libraries like boost::lambda, which can perform similarly.
EDIT: Upon reading your question again, it looks like you might be looking for anonymous functions in C++. If that's what you want, unfortunately the language does not support that feature. C++ requires you be a bit more verbose with those sorts of things at present time. If you need more than what boost::lamda is already providing you then you should probably separate it out as a normal function anyway.
In C and C++ this is accomplished using function pointers or functors and templates (C++ only).
For example (using the C++ way (functors))
//Define a functor. A functor is nothing but a class which overloads
//operator(). Inheriting from std::binary_function allows your functor
//to operate cleanly with STL algorithms.
struct MyFunctor : public std::binary_function<int, int, bool>
{
bool operator()(int a, int b) {
return a < b;
};
};
//Define a template which takes a functor type. Your functor should be
//should be passed by value into the target function, and a functor should
//not have internal state, making this copy cheap.
template <typename Func_T>
void MyFunctionUsingACallback(Func_T functor)
{
if (functor(a, b))
//Do something
else
//Do something else
}
//Example usage.
int main()
{
MyFunctionUsingACallback(MyFunctor());
}
Using the C way (function pointers):
//Create a typedef for a function pointer type taking a pair of ints and
//returning a boolean value.
typedef bool (*Functor_T)(int, int);
//An example callback function.
bool MyFunctor(int a, int b)
{
return a < b;
}
//Note that you use the typedef'd function here.
void MyFunctionUsingACallback(Functor_T functor)
{
if (functor(a, b))
//Do something
else
//Do something else
}
//Example usage.
int main()
{
MyFunctionUsingACallback(MyFunctor);
}
Note that you should prefer the C++ way because it will allow the compiler to
make more intelligent decisions with regards to inlining, unless for some reason
you are limited to the C subset.