4

I am mainly a .NET programmer working on a C++ project and am trying to determine the equivalent way to handle delegates that use the Action and Function template types. I use the delegates both as events and callbacks within the .NET code. My C++ project uses smart pointers and the same delegate design patterns as a C# program would. What is the best way to handle this situation? It is not clear to me how to pass and maintain a function pointer that also keeps track of the smart pointer and potentially the deletion of the underlying object since the event container uses a weak reference. The library needs to be multi-platform so using CLR is unfortunately not an option.

Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
John
  • 791
  • 1
  • 6
  • 22

2 Answers2

1

What you are looking for is a method pointer bound to an existing object, that's it ?

The you should have a look for boost::bind. If your environment supports it, you can also use std::tr1::bind or even std::bind if it supports C++11.

The example which illustrates what you want is :

struct X
{
    bool f(int a);
};
X x;
shared_ptr<X> p(new X);
int i = 5;

bind(&X::f, ref(x), _1)(i);     // x.f(i)
bind(&X::f, &x, _1)(i);         //(&x)->f(i)
bind(&X::f, x, _1)(i);          // (internal copy of x).f(i)
bind(&X::f, p, _1)(i);          // (internal copy of p)->f(i)

The last two examples are interesting in that they produce "self-contained" function objects. bind(&X::f, x, _1) stores a copy of x. bind(&X::f, p, _1) stores a copy of p, and since p is a boost::shared_ptr, the function object retains a reference to its instance of X and will remain valid even when p goes out of scope or is reset().

For the differences between boost::bind, std::tr1::bind and std::bind, I let you see this other question on SO.

Community
  • 1
  • 1
Jaffa
  • 12,442
  • 4
  • 49
  • 101
  • The problem with boost::bind is that I am developing a shared library and might have a boost version conflict between the client application boost version and the library boost version. Is there a clean way to handle this situation? – John Dec 11 '12 at 18:50
  • 1
    It is a clean way, and you can set boost versions requirements. And that kind of functions won't change overtime (low probability at least). Have you considered the fact that it's an header-only ? And the fact that boost::bind has been integrated in the new standard, C++11 ? And were beforehand part of the TR1 ? – Jaffa Dec 12 '12 at 06:16
  • I need to use boost::signals to get the event functionality and lifetime control that comes with a C# type "event". Is boost considered a reasonable dependency these days? – John Dec 17 '12 at 01:58
  • I don't know why you need that, it works like that. The only difference is that events are in fact arrays but you can easily do the same. But yes, boost is a reasonable dependency =) – Jaffa Dec 17 '12 at 07:05
0

Take a look at: http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible

It will also explain why delegates in C++ are a little tricky. This library was recommend in a game development book i read (So i'm assuming its very fast).

Alec Thilenius
  • 524
  • 5
  • 12