Messaging system: Callbacks can be anything - c++

I'm trying to write an event system for my game. The callbacks that my event manager will store can be both plain functions as well as functors. I also need to be able to compare functions/functors so I know which one I need to disconnect from the event manager.
• Initially I tried using boost::function; it handles functions and functors perfectly well, except it has no operator==, so I can't remove callbacks if I want to.
class EventManager
{
typedef boost::function<void (boost::weak_ptr<Event>)> Callback;
std::map<Event::Type, std::vector<Callback>> eventHandlerMap_;
};
• I also tried using boost::signal, but that also gives me a compilation problem related to operator==:
binary '==' : no operator found which takes a left-hand operand of type 'const Functor' (or there is no acceptable conversion)
void test(int c) {
std::cout << "test(" << c << ")";
}
struct Functor
{
void operator()(int g) {
std::cout << "Functor::operator(" << g << ")";
}
};
int main()
{
boost::signal<void (int)> sig;
Functor f;
sig.connect(test);
sig.connect(f);
sig(7);
sig.disconnect(f); // Error
}
Any other suggestions about how I might implement this? Or maybe how I can make either boost:: function or boost::signal work? (I'd rather use boost:: function though, since I've heard signal is rather slow for small collections of items.)
Edit: This is the interface of that I'd like EventManager to have.
class EventManager
{
public:
void addEventHandler(Event::Type evType, Callback func);
void removeEventHandler(Event::Type evType, Callback func);
void queueEvent(boost::shared_ptr<Event> ev);
void dispatchNextEvent();
};

You'll find that most generic function wrappers do not support function equality.
Why is this? Well, just look at your functor there:
struct Functor
{
void operator()(int g) {
std::cout << "Functor::operator(" << g << ")";
}
};
This Functor has no operator==, and therefore cannot be compared for equality. So when you pass it to boost::signal by value, a new instance is created; this will compare false for pointer-equality, and has no operator to test for value-equality.
Most functors don't, in fact, have value-equality predicates. It's not useful very much. The usual way to deal with this is to have a handle to the callback instead; boost::signals does this with its connection object. For example, take a look at this example from the documentation:
boost::signals::connection c = sig.connect(HelloWorld());
if (c.connected()) {
// c is still connected to the signal
sig(); // Prints "Hello, World!"
}
c.disconnect(); // Disconnect the HelloWorld object
assert(!c.connected()); c isn't connected any more
sig(); // Does nothing: there are no connected slots
With this, HelloWorld doesn't need to have an operator==, as you're referring directly to the signal registration.

Have you ever tried libsigc and libsigc++? I started using them in linux and fell in love with them. I now use them in my Windows applications as well. I believe it is more extensible and flexible than boost. It is also a breeze to implement.

I highly recommend you consider Don Clugston's "Member Function Pointers and the Fastest Possible C++ Delegates". You can find the article and download the code from here:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Among many other benefits, his delegates provide comparison operators (==, !=, <) out of the box. I'm currently using them for a realtime system and find them excellent in every way. I do seem to recall we had to make a minor modification to fix a compiler portability issue; but, that experience will vary based on platform etc.
Also, the article is several years old so you may want to google around for updated code/discussion regarding this delegate implementation if you run into any problems.

No matter, I found the solution. A little template magic and things become simple(r):
template<typename F>
void EventManager::removeEventHandler(Event::Type evType, F func)
{
auto compare = [func](const Callback& other) -> bool {
F const* f = other.target<F>();
if (f == nullptr) return false;
return *f == func;
};
std::vector<Callback>& callbacks = ...;
auto pend = std::remove_if(callbacks.begin(), callbacks.end(), compare);
callbacks.erase(pend, callbacks.end());
}
template<typename R, typename F, typename L>
void EventManager::removeEventHandler(
Event::Type evType, const boost::_bi::bind_t<R, F, L>& func)
{
auto compare = [&func](const Callback& other) -> bool {
auto const* f = other.target<boost::_bi::bind_t<R, F, L>>();
if (f == nullptr) return false;
return func.compare(*f);
};
std::vector<Callback>& callbacks = ...;
auto pend = std::remove_if(callbacks.begin(), callbacks.end(), compare);
callbacks.erase(pend, callbacks.end());
}
I need to handle Boost.Bind objects separately because operator== doesn't actually do comparison for Bind objects, but produce a new functor that compares the result of the other two (read more). To compare Boost.Bind you have to use the member function compare().
The type boost::_bi::bind_t seems to be an internal type of Boost (I guess that's what the underscore in namespace '_bi' means), however it should be safe to use it as all overloads of boost::function_equal also use this type (reference).
This code will work for all types of functors as long as there is an operator== defined that does comparison, or if you're using Boost.Bind. I had a superficial look into std::bind (C++0x), but that doesn't seem to be comparable, so it won't work with the code I posted above.

Related

Replace function-pointer implementation with std::function for using lambdas in PlayFab SDK

I'm currently trying to include the PlayFab C++ SDK into my app. This SDK is mainly for the game engine Cocos2d-x, but can be used for any C++ app basically.
It's just plain REST, hence you send requests to their servers and wait for the response. This would be perfect for using lambdas.
They declare this callback, which is called when a request is successful:
template<typename ResType> using ProcessApiCallback = void(*)(const ResType& result, void* userData);
Unfortunately, they're not using std::function, but a function pointer. This way one can not use lambdas that capture variables.
Hence, I thought I could simply replace this function pointer callback with an std::function callback like so:
template<typename ResType> using ProcessApiCallback = std::function<void(const ResType& result, void* userData)>;
Unfortunately, things are not that simply, as they stored the function pointers using ugly reinterpret_casts, here's an example (remove unnecessary parts to keep it short):
void PlayFabClientAPI::LoginWithAndroidDeviceID(
LoginWithAndroidDeviceIDRequest& request,
ProcessApiCallback<LoginResult> callback,
ErrorCallback errorCallback,
void* userData
)
{
// here they assign the callback to the httpRequest
httpRequest->SetResultCallback(reinterpret_cast<void*>(callback));
httpRequest->SetErrorCallback(errorCallback);
httpRequest->SetUserData(userData);
PlayFabSettings::httpRequester->AddRequest(httpRequest, OnLoginWithAndroidDeviceIDResult, userData);
}
Later on, when the request was successful, they do this:
if (request->GetResultCallback() != nullptr)
{
ProcessApiCallback<LoginResult> successCallback = reinterpret_cast<ProcessApiCallback<LoginResult>>(request->GetResultCallback());
successCallback(outResult, request->GetUserData());
}
The HttpRequest class has this field:
void* mResultCallback;
The problem is that I don't know how to store arbitrary std::function pointers in the HttpRequest class and then later cast them back. I tried many things, including also really ugly reinterpret_casting, but nothing did work.
I'm open to do any changes to their SDK. I also reported this as bad design and they agreed, but they don't have the time to improve it, but they will accept pull request if a good solution can be found.
The key item of information here is the userData pointer. It is supplied as part of the request, and it gets passed back to your callback function. This is an opaque pointer that the library pays no attention to, otherwise, except to forward it to your callback.
And this is what you will use, here.
This is a very common design pattern with generic service-oriented libraries that are written in C. Their APIs are often structured this way: they accept a request with an extra opaque pointer. They store this pointer, and they pass it back to the user-supplied callback, when the request completes.
The callback, then, uses it to associated any kind of additional metadata with the request.
This is a C++ library, but they chose to implement a C-style design pattern for library callbacks. That's unfortunate.
But, anyway, in your case you're going to dynamically allocate either your std::function, or some class's instance that contains your std::function, and any other data it needs, and pass the pointer to the dynamically-allocated structure to the request.
When your callback gets invoked, it simply needs to reinterpret_cast the opaque pointer to the dynamically-allocated type, copy its contents, delete it (in order to avoid memory leaks, of course), then proceed to use the copied contents as part of the callback action (whether it involves invoking the std::function, or something else, is immaterial).
Given that this is a C++ library you're using, and not a C library, it is unfortunate that they chose to implement this C-style opaque pointer pass-through design pattern. There are, of course, better ways to implement this in C++, but this is what you have to work with, so you'll have to deal with one ugly reintepret_cast. No way to avoid it.
To elaborate a bit on the answer by #SamVarshavchik here's a code snippet which should handle most of the process of generating a userData pointer and a "stateless" callback function taking the userData for you:
#include <memory>
#include <utility>
#include <type_traits>
#include <iostream>
template <typename T, typename... Args>
void c_callback_adaptor(Args... args, void* userData) {
auto callable = reinterpret_cast<T*>(userData);
(*callable)(args...);
}
template <typename Fn>
struct genCCallback_impl;
template <typename Res, typename... Args>
struct genCCallback_impl<Res(Args...)> {
template <typename T>
static std::pair<std::unique_ptr<std::decay_t<T>>,
Res (*)(Args..., void*)>
gen(T&& callable) {
return std::make_pair(
std::make_unique<std::decay_t<T>>(std::forward<T>(callable)),
c_callback_adaptor<std::decay_t<T>, Args...>);
}
};
template <typename Fn, typename T>
auto genCCallback(T&& callable) {
return genCCallback_impl<Fn>::gen(std::forward<T>(callable));
}
And a simple example of usage:
extern void registerCallback(void (*callbackFn)(int, int, void*), void* userData);
void test(int n) {
auto cCallback = genCCallback<void(int, int)>(
[n](int x, int y) {
std::cout << n << ' ' << x << ' ' << y << '\n';
});
registerCallback(cCallback.second, cCallback.first.get());
// for demo purposes make the allocated memory permanent
(void) cCallback.first.release();
}
(Of course, in actual code, you'd need to keep track of the std::unique_ptr until you're ready to unregister the callback.)
In answer to a comment: to break down what the templates are doing behind the scenes, suppose for illustration that the internal name of the lambda class is __lambda1. Then the test() function above generates code essentially equivalent to:
void c_callback_adaptor_lambda1(int x, int y, void* userData) {
auto callable = reinterpret_cast<__lambda1*>(userData);
(*callable)(x, y);
}
class __lambda1 {
public:
__lambda1(int n) { ... }
void operator()(int x, int y) const { std::cout << ...; }
...
private: ...
};
void test(int n) {
auto cCallback = std::make_pair(
std::make_unique<__lambda1>(n),
c_callback_adaptor_lambda1);
registerCallback(cCallback.second, cCallback.first.get());
(void) cCallback.first.release();
}
The PlayFab Cocos2dxSDK you have linked has since been upgraded to support lambda functions without modification to the SDK.
For Example:
PlayFabClientAPI::LoginWithEmailAddress(request,
[](const LoginResult& result, void* customData) { /* your login-success lambda here */ },
[](const PlayFabError& error, void* customData) { /* your error lambda here */ },
nullptr);

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.

What is the practical use of pointers to member functions?

I've read through this article, and what I take from it is that when you want to call a pointer to a member function, you need an instance (either a pointer to one or a stack-reference) and call it so:
(instance.*mem_func_ptr)(..)
or
(instance->*mem_func_ptr)(..)
My question is based on this: since you have the instance, why not call the member function directly, like so:
instance.mem_func(..) //or: instance->mem_func(..)
What is the rational/practical use of pointers to member functions?
[edit]
I'm playing with X-development & reached the stage where I am implementing widgets; the event-loop-thread for translating the X-events to my classes & widgets needs to start threads for each widget/window when an event for them arrives; to do this properly I thought I needed function-pointers to the event-handlers in my classes.
Not so: what I did discover was that I could do the same thing in a much clearer & neater way by simply using a virtual base class. No need whatsoever for pointers to member-functions. It was while developing the above that the doubt about the practical usability/meaning of pointers to member-functions arose.
The simple fact that you need a reference to an instance in order to use the member-function-pointer, obsoletes the need for one.
[edit - #sbi & others]
Here is a sample program to illustrate my point:
(Note specifically 'Handle_THREE()')
#include <iostream>
#include <string>
#include <map>
//-----------------------------------------------------------------------------
class Base
{
public:
~Base() {}
virtual void Handler(std::string sItem) = 0;
};
//-----------------------------------------------------------------------------
typedef void (Base::*memfunc)(std::string);
//-----------------------------------------------------------------------------
class Paper : public Base
{
public:
Paper() {}
~Paper() {}
virtual void Handler(std::string sItem) { std::cout << "Handling paper\n"; }
};
//-----------------------------------------------------------------------------
class Wood : public Base
{
public:
Wood() {}
~Wood() {}
virtual void Handler(std::string sItem) { std::cout << "Handling wood\n"; }
};
//-----------------------------------------------------------------------------
class Glass : public Base
{
public:
Glass() {}
~Glass() {}
virtual void Handler(std::string sItem) { std::cout << "Handling glass\n"; }
};
//-----------------------------------------------------------------------------
std::map< std::string, memfunc > handlers;
void AddHandler(std::string sItem, memfunc f) { handlers[sItem] = f; }
//-----------------------------------------------------------------------------
std::map< Base*, memfunc > available_ONE;
void AddAvailable_ONE(Base *p, memfunc f) { available_ONE[p] = f; }
//-----------------------------------------------------------------------------
std::map< std::string, Base* > available_TWO;
void AddAvailable_TWO(std::string sItem, Base *p) { available_TWO[sItem] = p; }
//-----------------------------------------------------------------------------
void Handle_ONE(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
std::map< Base*, memfunc >::iterator it;
Base *inst = NULL;
for (it=available_ONE.begin(); ((it != available_ONE.end()) && (inst==NULL)); it++)
{
if (it->second == f) inst = it->first;
}
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_TWO(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
Base *inst = available_TWO[sItem];
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_THREE(std::string sItem)
{
Base *inst = available_TWO[sItem];
if (inst) inst->Handler(sItem);
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
int main()
{
Paper p;
Wood w;
Glass g;
AddHandler("Paper", (memfunc)(&Paper::Handler));
AddHandler("Wood", (memfunc)(&Wood::Handler));
AddHandler("Glass", (memfunc)(&Glass::Handler));
AddAvailable_ONE(&p, (memfunc)(&Paper::Handler));
AddAvailable_ONE(&g, (memfunc)(&Glass::Handler));
AddAvailable_TWO("Paper", &p);
AddAvailable_TWO("Glass", &g);
std::cout << "\nONE: (bug due to member-function address being relative to instance address)\n";
Handle_ONE("Paper");
Handle_ONE("Wood");
Handle_ONE("Glass");
Handle_ONE("Iron");
std::cout << "\nTWO:\n";
Handle_TWO("Paper");
Handle_TWO("Wood");
Handle_TWO("Glass");
Handle_TWO("Iron");
std::cout << "\nTHREE:\n";
Handle_THREE("Paper");
Handle_THREE("Wood");
Handle_THREE("Glass");
Handle_THREE("Iron");
}
{edit] Potential problem with direct-call in above example:
In Handler_THREE() the name of the method must be hard-coded, forcing changes to be made anywhere that it is used, to apply any change to the method. Using a pointer to member-function the only additional change to be made is where the pointer is created.
[edit] Practical uses gleaned from the answers:
From answer by Chubsdad:
What: A dedicated 'Caller'-function is used to invoke the mem-func-ptr;Benefit: To protect code using function(s) provided by other objectsHow: If the particular function(s) are used in many places and the name and/or parameters change, then you only need to change the name where it is allocated as pointer, and adapt the call in the 'Caller'-function. (If the function is used as instance.function() then it must be changed everywhere.)
From answer by Matthew Flaschen:
What: Local specialization in a classBenefit: Makes the code much clearer,simpler and easier to use and maintainHow: Replaces code that would conventionally be implement using complex logic with (potentially) large switch()/if-then statements with direct pointers to the specialization; fairly similar to the 'Caller'-function above.
The same reason you use any function pointer: You can use arbitrary program logic to set the function pointer variable before calling it. You could use a switch, an if/else, pass it into a function, whatever.
EDIT:
The example in the question does show that you can sometimes use virtual functions as an alternative to pointers to member functions. This shouldn't be surprising, because there are usually multiple approaches in programming.
Here's an example of a case where virtual functions probably don't make sense. Like the code in the OP, this is meant to illustrate, not to be particularly realistic. It shows a class with public test functions. These use internal, private, functions. The internal functions can only be called after a setup, and a teardown must be called afterwards.
#include <iostream>
class MemberDemo;
typedef void (MemberDemo::*MemberDemoPtr)();
class MemberDemo
{
public:
void test1();
void test2();
private:
void test1_internal();
void test2_internal();
void do_with_setup_teardown(MemberDemoPtr p);
};
void MemberDemo::test1()
{
do_with_setup_teardown(&MemberDemo::test1_internal);
}
void MemberDemo::test2()
{
do_with_setup_teardown(&MemberDemo::test2_internal);
}
void MemberDemo::test1_internal()
{
std::cout << "Test1" << std::endl;
}
void MemberDemo::test2_internal()
{
std::cout << "Test2" << std::endl;
}
void MemberDemo::do_with_setup_teardown(MemberDemoPtr mem_ptr)
{
std::cout << "Setup" << std::endl;
(this->*mem_ptr)();
std::cout << "Teardown" << std::endl;
}
int main()
{
MemberDemo m;
m.test1();
m.test2();
}
My question is based on this: since you have the instance, why not call the member function directly[?]
Upfront: In more than 15 years of C++ programming, I have used members pointers maybe twice or thrice. With virtual functions being around, there's not all that much use for it.
You would use them if you want to call a certain member functions on an object (or many objects) and you have to decide which member function to call before you can find out for which object(s) to call it on. Here is an example of someone wanting to do this.
I find the real usefulness of pointers to member functions comes when you look at a higher level construct such as boost::bind(). This will let you wrap a function call as an object that can be bound to a specific object instance later on and then passed around as a copyable object. This is a really powerful idiom that allows for deferred callbacks, delegates and sophisticated predicate operations. See my previous post for some examples:
https://stackoverflow.com/questions/1596139/hidden-features-and-dark-corners-of-stl/1596626#1596626
Member functions, like many function pointers, act as callbacks. You could manage without them by creating some abstract class that calls your method, but this can be a lot of extra work.
One common use is algorithms. In std::for_each, we may want to call a member function of the class of each member of our collection. We also may want to call the member function of our own class on each member of the collection - the latter requires boost::bind to achieve, the former can be done with the STL mem_fun family of classes (if we don't have a collection of shared_ptr, in which case we need to boost::bind in this case too). We could also use a member function as a predicate in certain lookup or sort algorithms. (This removes our need to write a custom class that overloads operator() to call a member of our class, we just pass it in directly to boost::bind).
The other use, as I mentioned, are callbacks, often in event-driven code. When an operation has completed we want a method of our class called to handle the completion. This can often be wrapped into a boost::bind functor. In this case we have to be very careful to manage the lifetime of these objects correctly and their thread-safety (especially as it can be very hard to debug if something goes wrong). Still, it once again can save us from writing large amounts of "wrapper" code.
There are many practical uses. One that comes to my mind is as follows:
Assume a core function such as below (suitably defined myfoo and MFN)
void dosomething(myfoo &m, MFN f){ // m could also be passed by reference to
// const
m.*f();
}
Such a function in the presence of pointer to member functions, becomes open for extension and closed for modification (OCP)
Also refer to Safe bool idiom which smartly uses pointer to members.
The best use of pointers to member functions is to break dependencies.
Good example where pointer to member function is needed is Subscriber/Publisher pattern :
http://en.wikipedia.org/wiki/Publish/subscribe
In my opinion, member function pointers do are not terribly useful to the average programmer in their raw form. OTOH, constructs like ::std::tr1::function that wrap member function pointers together with a pointer to the object they're supposed to operate on are extremely useful.
Of course ::std::tr1::function is very complex. So I will give you a simple example that you wouldn't actually use in practice if you had ::std::tr1::function available:
// Button.hpp
#include <memory>
class Button {
public:
Button(/* stuff */) : hdlr_(0), myhandler_(false) { }
~Button() {
// stuff
if (myhandler_) {
delete hdlr_;
}
}
class PressedHandler {
public:
virtual ~PressedHandler() = 0;
virtual void buttonPushed(Button *button) = 0;
};
// ... lots of stuff
// This stores a pointer to the handler, but will not manage the
// storage. You are responsible for making sure the handler stays
// around as long as the Button object.
void setHandler(const PressedHandler &hdlr) {
hdlr_ = &hdlr;
myhandler_ = false;
}
// This stores a pointer to an object that Button does not manage. You
// are responsible for making sure this object stays around until Button
// goes away.
template <class T>
inline void setHandlerFunc(T &dest, void (T::*pushed)(Button *));
private:
const PressedHandler *hdlr_;
bool myhandler_;
template <class T>
class PressedHandlerT : public Button::PressedHandler {
public:
typedef void (T::*hdlrfuncptr_t)(Button *);
PressedHandlerT(T *ob, hdlrfuncptr_t hdlr) : ob_(ob), func_(hdlr) { }
virtual ~PressedHandlerT() {}
virtual void buttonPushed(Button *button) { (ob_->*func_)(button); }
private:
T * const ob_;
const hdlrfuncptr_t func_;
};
};
template <class T>
inline void Button::setHandlerFunc(T &dest, void (T::*pushed)(Button *))
{
PressedHandler *newhandler = new PressedHandlerT<T>(&dest, pushed);
if (myhandler_) {
delete hdlr_;
}
hdlr_ = newhandler;
myhandler_ = true;
}
// UseButton.cpp
#include "Button.hpp"
#include <memory>
class NoiseMaker {
public:
NoiseMaker();
void squee(Button *b);
void hiss(Button *b);
void boo(Button *b);
private:
typedef ::std::auto_ptr<Button> buttonptr_t;
const buttonptr_t squeebutton_, hissbutton_, boobutton_;
};
NoiseMaker::NoiseMaker()
: squeebutton_(new Button), hissbutton_(new Button), boobutton_(new Button)
{
squeebutton_->setHandlerFunc(*this, &NoiseMaker::squee);
hissbutton_->setHandlerFunc(*this, &NoiseMaker::hiss);
boobutton_->setHandlerFunc(*this, &NoiseMaker::boo);
}
Assuming Button is in a library and not alterable by you, I would enjoy seeing you implement that cleanly using a virtual base class without resorting to a switch or if else if construct somewhere.
The whole point of pointers of pointer-to-member function type is that they act as a run-time way to reference a specific method. When you use the "usual" syntax for method access
object.method();
pointer->method();
the method part is a fixed, compile-time specification of the method you want to call. It is hardcoded into your program. It can never change. But by using a pointer of pointer-to-member function type you can replace that fixed part with a variable, changeable at run-time specification of the method.
To better illustrate this, let me make the following simple analogy. Let's say you have an array
int a[100];
You can access its elements with fixed compile-time index
a[5]; a[8]; a[23];
In this case the specific indices are hardcoded into your program. But you can also access array's elements with a run-time index - an integer variable i
a[i];
the value of i is not fixed, it can change at run-time, thus allowing you to select different elements of the array at run-time. That is very similar to what pointers of pointer-to-member function type let you do.
The question you are asking ("since you have the instance, why not call the member function directly") can be translated into this array context. You are basically asking: "Why do we need a variable index access a[i], when we have direct compile-time constant access like a[1] and a[3]?" I hope you know the answer to this question and realize the value of run-time selection of specific array element.
The same applies to pointers of pointer-to-member function type: they, again, let you to perform run-time selection of a specific class method.
The use case is that you have several member methods with the same signature, and you want to build logic which one should be called under given circumstances. This can be helpful to implement state machine algorithms.
Not something you use everyday...
Imagine for a second you have a function that could call one of several different functions depending on parameters passed.
You could use a giant if/else if statement
You could use a switch statement
Or you could use a table of function pointers (a jump table)
If you have a lot of different options the jump table can be a much cleaner way of arranging your code ...
Its down to personal preference though. Switch statement and jump table correspond to more or less the same compiled code anyway :)
Member pointers + templates = pure win.
e.g. How to tell if class contains a certain member function in compile time
or
template<typename TContainer,
typename TProperty,
typename TElement = decltype(*Container().begin())>
TProperty grand_total(TContainer& items, TProperty (TElement::*property)() const)
{
TProperty accum = 0;
for( auto it = items.begin(), end = items.end(); it != end; ++it) {
accum += (it->*property)();
}
return accum;
}
auto ship_count = grand_total(invoice->lineItems, &LineItem::get_quantity);
auto sub_total = grand_total(invoice->lineItems, &LineItem::get_extended_total);
auto sales_tax = grand_total(invoice->lineItems, &LineItem::calculate_tax);
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
This is completely missing the point. There are two indepedent concerns here:
what action to take at some later point in time
what object to perform that action on
Having a reference to an instance satisfies the second requirement. Pointers to member functions address the first: they are a very direct way to record - at one point in a program's execution - which action should be taken at some later stage of execution, possibly by another part of the program.
EXAMPLE
Say you have a monkey that can kiss people or tickle them. At 6pm, your program should set the monkey loose, and knows whom the monkey should visit, but around 3pm your user will type in which action should be taken.
A beginner's approach
So, at 3pm you could set a variable "enum Action { Kiss, Tickle } action;", then at 6pm you could do something like "if (action == Kiss) monkey->kiss(person); else monkey->tickle(person)".
Issues
But that introducing an extra level of encoding (the Action type's introduced to support this - built in types could be used but would be more error prone and less inherently meaningful). Then - after having worked out what action should be taken at 3pm, at 6pm you have to redundantly consult that encoded value to decide which action to take, which will require another if/else or switch upon the encoded value. It's all clumsy, verbose, slow and error prone.
Member function pointers
A better way is to use a more specialised varibale - a member function pointer - that directly records which action to perform at 6pm. That's what a member function pointer is. It's a kiss-or-tickle selector that's set earlier, creating a "state" for the monkey - is it a tickler or a kisser - which can be used later. The later code just invokes whatever function's been set without having to think about the possibilities or have any if/else-if or switch statements.
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
Back to this. So, this is good if you make the decision about which action to take at compile time (i.e. a point X in your program, it'll definitely be a tickle). Function pointers are for when you're not sure, and want to decouple the setting of actions from the invocation of those actions.

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.

Creating multicast events with std::tr1::function (or boost::function)

I'm attempting to create C#-like multicast delegates and events using features from TR1. Or Boost, since boost::function is (mostly) the same as std::tr1::function. As a proof of concept I tried this:
template<typename T1>
class Event
{
private:
typedef std::tr1::function<void (T1)> action;
std::list<action> callbacks;
public:
inline void operator += (action func)
{
callbacks.push_back(func);
}
inline void operator -= (action func)
{
callbacks.remove(func);
}
void operator ()(T1 arg1)
{
for(std::list<action>::iterator iter = callbacks.begin();
iter != callbacks.end(); iter++)
{
(*iter)(arg1);
}
}
};
Which works, sort of. The line callbacks.remove(func) does not. When I compile it, I get the following error:
error C2451: conditional expression of type 'void' is illegal
Which is caused by line 1194 of the list header, which is in the remove function. What is causing this?
If you're you're looking for multicast delegates in C++, your best bet would be Boost.Signals2. You can also use Boost.Bind to make it possible to use member functions for callbacks.
You can look at my example here for simple usage of Boost.Signals and Boost.Bind.
Boost.Signal provides lifetime management facilities to ensure that events are not published to subscribers that no longer exist.
I think this is exactly same problem: comparing-stdtr1function-objects
(basically you can't compare functors, that's why erase or anything using operator== won't work)
You should look into Sutter's Generalizing Observer