Followers 0

# Mediator Pattern Help!

## 1 post in this topic

Hey all,

I'm writing a Mediator class in C++ and am having trouble with a part of it.  I've done this before in C# (which was really easy) and trying to do the same thing in C++ is kicking my butt.  I have a std::map that contains a std::string for the key and a std::vector<> for the value.  The idea being any number of functions/methods can be registered under any number of keys and all said functions/methods can be invoked with one call.

I'm having two primary problems:  1, I can't figure out how to get both functions AND class methods into the std::map.  Currently I'm using:

typedef std::function<void(void* Object)> FunctionDef;


I have a Register method in my Mediator class that takes a std::string for the key and a FunctionDef for the value.  So far this works fine for functions but I can't get it to work with class methods.

And 2;  I have an Unregister method in my Mediator class that takes the same inputs and removes the appropriate function from the appropriate key.  Or, at least, it's supposed too.

template<class T>
static void Unregister(std::string Key, T Function)
{
if (MediatorMap.count(Key) != 0)
{
FunctionDef Func = Function;
for (std::vector<FunctionDef>::iterator It = MediatorMap[Key].begin();
It != MediatorMap[Key].end();
++It)
{
if ((*It).target_type().name() == Func.target_type().name())
{
std::cout << "1" << std::endl;

std::cout << (*It).target<T>() << " == " << Func.target<T>() << " ?? \n";
if ((*It).target<T>() == Func.target<T>())
{
std::cout << "2" << std::endl;
}
}
}

if (MediatorMap[Key].size() == 0)
{
MediatorMap.erase(MediatorMap.find(Key));
}
}
}


This is basicaly just testing code ATM.  The problem seems to be, and mind you I can only test this with functions, that whatever info is provided by .target<T>() (I'm guessing the pointer) never matches, even when sending the same function.

I admit to not really being sure of what I'm doing.  This is new territory for me and my C++ is a little rusty.  Any help would be appreciated.

0

##### Share on other sites

Regarding 1):

Instead of trying to assign a member function pointer (which will obviously not work because member functions have a different signature), assign a lambda:

MyObject obj;
//...
FunctionDef myFunction = [&] () { obj.memberFunctionToCall(); };


Warning: there are a lot of caveats regarding what to capture in the lambda and how to do it regarding the lifetime of the objects involved. Unless you know what you are doing exactly I would strongly recommend you post some use case examples and how you intend to use this.

Regarding 2):

That is impossible. As [url=http://en.cppreference.com/w/cpp/utility/functional/function/operator_cmp]the documentation[/url] says: any non-empty std::function objects will always compare non-equal. Even if they were created using the same source-function. Even if they are copies of each other.

The typical way to solve this is returning some kind of Connection-object which uniquely identifies that particular connection. See for example how boost::signals2 works.

1

## Create an account

Register a new account