c++ store a pointer to a member function of unknown class - c++

I want to store a pointer to an object and a pointer to it's method of known signature. If I know the class then this pointer have type:
int (MyClass::*pt2Member)(float, char, char)
But how can i store the pointer if i don't know the type?
I want to do something like this:
myObject.callThisFuncLater(&otherObject, &otherObject::method)
How can i store a pointer to method method in myObject and call it later ?

The easiest way to do it if you have access to the TR1 STL library extensions (available on gcc and Visual Studio 2008 and onwards is. std::function and std::bind can be used to wrap an invocation which can be called later. This functionality is also available in boost function and boost bind:
#include <functional>
class MyClass {
public:
template<typename T> callThisFuncLater(T& otherObject,
int(T::*)(float, char, char) method) {
return storedInvocation_ = std::bind(otherObject,
method,
std::placeholders::_1, // float
std::placeholders::_2, // char
std::placeholders::_3); // char
}
int callStoredInvocation(float a, char b, char c) {
storedInvocation_(a, b, c);
}
private:
std::function<int(float, char, char)> storedInvocation_;
};

There is no simple way of doing this as originally built into the language or standard library (although, it has recently been added). If you're familiar with Boost, they include a solution for this - Boost.Function.
If for some reason, however, you're unable or unwilling to use Boost, there is a generic way of doing this using templates (which, admittedly, is rather similar to Boost's solution):
class FncPtr
{
public:
virtual int call(float, char, char) = 0;
};
template <typename T>
class ClassFncPtr : public FncPtr
{
int (T::*pt2Member)(float, char, char);
T *inst;
public:
ClassFncPtr(T* who, int (T::*memfunc)(float,char,char))
: inst(who), pt2Member(memfunc)
{
}
int call(float a, char b, char c)
{
return (inst->*pt2Member)(a,b,c);
}
};
template <typename T>
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char))
{
return new ClassFncPtr<T>(who,memfunc);
}
You can also subclass FncPtr to be able to use non-class functions, if you'd like.

You can use boost::function (and boost::bind) to store a piece of code to be called later.
class MyClass
{
public:
void callThisFuncLater( boost::function< int (float, char, char) > callBack );
};
...
myObject.callThisFuncLater( boost::bind( &otherObject::method, &otherObject ) );

Personally I would choose a different design. Simply because member function pointers in C++ are not easy to work with. Personally I would choose to use interfaces and inherit from these and parse along these.
One of the problems with member function pointers is that they are implemented differently on different compilers. If you use the Borland/Embarcardero compilers and want to limit yourself to this, you can use the __closure keyword, however most likely you are not, and therefore you would have to either use some other compiler specific implementation, or use one of the boost helper classes like function.
But if you are in a situation where you find it helpful to use member function pointers in C++, reconsider your design.

Related

Implementing an any container

I'm well aware of boost::any and boost::variant, but in this instance they don't fit my needs.
Normally, to contain an object of unknown type, one would derive it from a common base and access the instance through virtual methods. But, what can one do if it's impossible to use a common base?
I know that in this example you would have to know the contained type, but bear with me. std::vector is a template class with top level class also being a template. As far as I know it cannot be given a non-template base without modifying the STL headers. Now, lets say I want to create a vector of a single type but the containing class doesn't care about the type, but it does require access to some of the 'common' methods, size() and pop_back() for example.
Using boost::any, the type has been erased, making it almost impossible to dereference the contained object. boost::variant and tuple require knowing before hand what types may be inserted, causing the containing class to itself be a template.
What I have so far is something like this:
struct container
{
virtual ~container() = 0;
virtual void pop_back() = 0;
virtual size_t size() = 0;
...
}
template < typename T >
struct contained
{
std::vector< T > _vec;
contained ( size_t n, T _what ) : _vec( n, _what ) {}
virtual void pop_back() { _vec.pop_back(); }
...
}
class some_class
{
container* _cont;
template < typename T >
void create ( T _first ) { _cont = new contained< T >(1,_first); }
...
}
Here the client can call on create() and the template parameter should be determined automatically. Not a great example I know, but I'm trying to hide the template parameters from the client. Without doing this, some_class would have to also keep track of what type is being stored.
My method relies on virtual calls which causes a performance loss, especially when the internal class has virtual methods of it's own.
Are there any other types of containers that would better suit my needs?
Ideally, I'd like something like this
container = std::vector< T >;
container.pop_back();
container.push_back( T2 ); // compile error if types don't match
Where internally it would track the type and do a simple cast rather than rely on virtual methods. Almost like auto with the difference being that once declared it's type can change.
Edit:
In reality, I want to create a wrapper around std::basic_filebuf. This wrapper class opens the file with char,wchar_t or unsigned long based on the BOM. The wrapper is also derived from basic_filebuf with the template parameter being whatever the client chooses. Internally, it converts unicode code points from the file to the clients desired encoding. The problem arises when storing the internal basic_filebuf because it can be declared with any type as the template parameter. I don't want to use template specialization because I want the client to be able to pass in their own basic_filebuf instance.
Must be VS2010 compatible, which has limited features from C++11.
This cannot be combined with compile-time type checking. Based on your "ideally" example:
container c;
if (thingKnownAtRunTime()) {
c = vector<int>;
} else {
c = vector<string>;
}
c.push_back("hello world");
For the filebuf case, though, you might get good enough with something like (warning: untested)
template<typename FILEBUF>
void gensputc(FILEBUF* fb, long long c) {
FILEBUf::char_type c2 = smart_convert<FILEBUf::char_type>(c);
fb->sputc(c2);
}
class FileBufWrapper {
public:
template<typename FILEBUF> FileBufWrapper(FILEBUF* fb) {
fb_ = fb;
sputc_ = gensputc<FILEBUF>;
}
void sputc(long long c) {
sputc_(fb_,c);
}
private:
typedef void(*sputc_t)(void*, long long);
sputc_t sputc_;
void* fb_;
};
The smart_convert function throws a runtime exception if the value cannot be converted to the char type. Also, this needs to be done for every function you intend to call.
If you have access to c++11's std::function and std::bind, this can be made a little cleaner, especially for the cases where you don't need to convert anything.

What is a C++ delegate?

What is the general idea of a delegate in C++? What are they, how are they used and what are they used for?
I'd like to first learn about them in a 'black box' way, but a bit of information on the guts of these things would be great too.
This is not C++ at its purest or cleanest, but I notice that the codebase where I work has them in abundance. I'm hoping to understand them enough, so I can just use them and not have to delve into the horrible nested template awfulness.
These two The Code Project articles explain what I mean but not particularly succinctly:
Member Function Pointers and the Fastest Possible C++ Delegates
The Impossibly Fast C++ Delegates
You have an incredible number of choices to achieve delegates in C++. Here are the ones that came to my mind.
Option 1 : functors:
A function object may be created by implementing operator()
struct Functor
{
// Normal class/struct members
int operator()(double d) // Arbitrary return types and parameter list
{
return (int) d + 1;
}
};
// Use:
Functor f;
int i = f(3.14);
Option 2: lambda expressions (C++11 only)
// Syntax is roughly: [capture](parameter list) -> return type {block}
// Some shortcuts exist
auto func = [](int i) -> double { return 2*i/1.15; };
double d = func(1);
Option 3: function pointers
int f(double d) { ... }
typedef int (*MyFuncT) (double d);
MyFuncT fp = &f;
int a = fp(3.14);
Option 4: pointer to member functions (fastest solution)
See Fast C++ Delegate (on The Code Project).
struct DelegateList
{
int f1(double d) { }
int f2(double d) { }
};
typedef int (DelegateList::* DelegateType)(double d);
DelegateType d = &DelegateList::f1;
DelegateList list;
int a = (list.*d)(3.14);
Option 5: std::function
(or boost::function if your standard library doesn't support it). It is slower, but it is the most flexible.
#include <functional>
std::function<int(double)> f = [can be set to about anything in this answer]
// Usually more useful as a parameter to another functions
Option 6: binding (using std::bind)
Allows setting some parameters in advance, convenient to call a member function for instance.
struct MyClass
{
int DoStuff(double d); // actually a DoStuff(MyClass* this, double d)
};
std::function<int(double d)> f = std::bind(&MyClass::DoStuff, this, std::placeholders::_1);
// auto f = std::bind(...); in C++11
Option 7: templates
Accept anything as long as it matches the argument list.
template <class FunctionT>
int DoSomething(FunctionT func)
{
return func(3.14);
}
A delegate is a class that wraps a pointer or reference to an object instance, a member method of that object's class to be called on that object instance, and provides a method to trigger that call.
Here's an example:
template <class T>
class CCallback
{
public:
typedef void (T::*fn)( int anArg );
CCallback(T& trg, fn op)
: m_rTarget(trg)
, m_Operation(op)
{
}
void Execute( int in )
{
(m_rTarget.*m_Operation)( in );
}
private:
CCallback();
CCallback( const CCallback& );
T& m_rTarget;
fn m_Operation;
};
class A
{
public:
virtual void Fn( int i )
{
}
};
int main( int /*argc*/, char * /*argv*/ )
{
A a;
CCallback<A> cbk( a, &A::Fn );
cbk.Execute( 3 );
}
The need for C++ delegate implementations are a long lasting embarassment to the C++ community.
Every C++ programmer would love to have them, so they eventually use them despite the facts that:
std::function() uses heap operations (and is out of reach for serious embedded programming).
All other implementations make concessions towards either portability or standard conformity to larger or lesser degrees (please verify by inspecting the various delegate implementations here and on codeproject). I have yet to see an implementation which does not use wild reinterpret_casts, Nested class "prototypes" which hopefully produce function pointers of the same size as the one passed in by the user, compiler tricks like first forward declare, then typedef then declare again, this time inheriting from another class or similar shady techniques. While it is a great accomplishment for the implementers who built that, it is still a sad testimoney on how C++ evolves.
Only rarely is it pointed out, that now over 3 C++ standard revisions, delegates were not properly addressed. (Or the lack of language features which allow for straightforward delegate implementations.)
With the way C++11 lambda functions are defined by the standard (each lambda has anonymous, different type), the situation has only improved in some use cases. But for the use case of using delegates in (DLL) library APIs, lambdas alone are still not usable. The common technique here, is to first pack the lambda into a std::function and then pass it across the API.
Very simply, a delegate provides functionality for how a function pointer SHOULD work. There are many limitations of function pointers in C++. A delegate uses some behind-the-scenes template nastyness to create a template-class function-pointer-type-thing that works in the way you might want it to.
ie - you can set them to point at a given function and you can pass them around and call them whenever and wherever you like.
There are some very good examples here:
http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates
http://www.codeproject.com/Articles/13287/Fast-C-Delegate
An option for delegates in C++ that is not otherwise mentioned here is to do it C style using a function ptr and a context argument. This is probably the same pattern that many asking this question are trying to avoid. But, the pattern is portable, efficient, and is usable in embedded and kernel code.
class SomeClass
{
in someMember;
int SomeFunc( int);
static void EventFunc( void* this__, int a, int b, int c)
{
SomeClass* this_ = static_cast< SomeClass*>( this__);
this_->SomeFunc( a );
this_->someMember = b + c;
}
};
void ScheduleEvent( void (*delegateFunc)( void*, int, int, int), void* delegateContext);
...
SomeClass* someObject = new SomeObject();
...
ScheduleEvent( SomeClass::EventFunc, someObject);
...
Windows Runtime equivalent of a function object in standard C++. One can use the whole function as a parameter (actually that is a function pointer). It is mostly used in conjunction with events. The delegate represents a contract that event handlers much fulfill. It facilitate how a function pointer can work for.

mem_func and virtual function

I have the following classes:
class A
{
public:
virtual void myfunc(unsigned char c, std::string* dest) = 0;
};
class B : public class A
{
public:
virtual void myfunc(unsigned char c, std::string* dest);
};
void someOtherFunc(const std::string& str,A *pointerFunc)
{
std::string tmp;
for_each(str.begin(),
str.end(),
std::bind2nd(std::mem_fun(pointerFunc->myfunc), &tmp));
}
I get the following compilation error:
error: no matching function for call to \u2018mem_fun()\u2019
Do you know why?
You're looking for std::mem_fun(&A::myfunc).
EDIT: You can't use mem_fun at all here -- no overload of mem_fun allows you to make a two argument member function into a functor. You're going to have to use something like boost::bind/std::tr1::bind (If you have TR1)/std::bind (If you have C++0x) or you're going to have to write your own functor.
Note that even if mem_fun was able to do this sort of binding, then std::bind2nd would fail, because bind2nd expects a functor taking two arguments, and binding a member function pointer like this is going to produce a functor with three arguments.
You have a few ways around this:
Write your own functor that does what you want.
Write an explicit loop instead of std::for_each.
One of the not-yet-standard binder functions I mentioned above (and demonstrated in #David's answer)
Don't bother with the virtual function in the first place -- make your method accept a plain function pointer and implement things in terms of the function pointer. Of course this only works if myfunc doesn't depend on members of the class to which it belongs (in which case it shouldn't have ever been put into a class in the first place)
What you are trying to use here is use a pointer to a member function to apply a member function of another object to every object in the container. Apparently none of the adapters will work in this case. In that case the only solution is to write a special wrapper functor class for it.
Looking at the implementation behind of std::mem_fun you should be able to write your own:
EDIT (made it "human-readable")
template<class Result, class Ty, class Arg>
class mem_fun1_t : public binary_function<Ty*, Arg, Result>
{
private:
Result (Ty::*m_mf)(Arg);
public:
mem_fun1_t(Result (Ty::*mf)(Arg)) : m_mf(mf) { }
Result operator()(Ty* pLeft, Arg Right) const {
return ((pLleft->*m_mf)(Right));
}
};
Your declaration does not represent what you want to do.
try:
void someOtherFunc(const std::string& str)
{
std::string tmp;
B BInstance;
A* ptrToB = &BInstance;
for_each(str.begin(),
str.end(),
boost::bind(&A::myfunc, ptrToB, _1, &tmp));
}
this (or a variation of) should do what you want.

Passing void(*) in C++

I have a std::map which I'm trying to store void pointers for the values. The problem is, most of the pointer I'm trying to store are methods in a class and have different amount of params. I know for the params I can use a va list so thats not too much of a problem, the problem would be the actual pointer itself.
This is what I have:
class A
{
public:
A();
void methodA(...);
};
class B
{
public:
B();
void methodB(...);
};
void method_no_class(...) { }
std::map<int, void(*)(...)> my_map;
my_map[0] = &method_no_class;
B* cb = new B();
my_map[1] = &cb->methodB; // will return error
Maybe this information my help you:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
Pointer to method is of different type than pointer to function. If you want to store them both in single collection you have to do manual casts.
The clean OO way would be to define a command interface. The interface would take an instance (of A or B) and all parameters. In the invoke() method, it would call the method of the instance.
You could then use a map of these command interfaces (just define a common subclass for them which defines the abstract invoke() method). The compiler would check all types and arguments for you, and you wouldn't have to use varargs.
Following up on Kamil Szot's answer, the C++ FAQ (and the book) is an excellent reference to the murky depths of C++ and object oriented programming in general. Section 33 addresses specifically the problem you are having:
In C++, member functions have an implicit parameter which points to the object (the this pointer inside the member function). Normal C functions can be thought of as having a different calling convention from member functions, so the types of their pointers (pointer-to-member-function vs. pointer-to-function) are different and incompatible.
Of course, the answer to your question is somewhat lacking in details.
You might want to look at method operaters ->, ::, and their friends. I'll try to find a better link but start here.
UPDATE: hopefully this is a better article for method pointers and operators.
You should functionoids here. They can be used as a flexible and type safe replacement for function pointers with different signatures. A abstract base class is needed. It contains the actual function invocation with the common parameters, if there are any.
class Functioniod: public YourClass {
virtual void execute(char d, common_parameters,...) = 0
}
For every function you want to use, you create a derived class. The constructor contains the function-specific parameters, and the execute() function the actual call. This execute function is later called instead of the function pointer. It needs to have the same signature in every functionoid. It could call something different in any other class too, of course.
class FuncA: public Functionoid {
FuncA(int _a, float _b, string _c, function-specific-parameters...) {
a = _a; b = _b; c = _c;
}
void execute(char d, common-parameters,...) {
call-to-member(d, a, b, c);
}
int a;
float b;
string c;
}
Now if you want to use this as a replacement for your member function pointer, you would do:
std::map<int, *Functionoid> my_map;
my_map[0] = new FuncA(someInt, someFloat, someString);
my_map[1] = new FuncB(some-other-parameters...);
and execute them with
my_map[0]->execute(common-parm);
my_map[1]->execute(common-parm);
Here's an example code to get you started. Haven't compiled it, so might require some tuning.
#define func(Instance,Method,Class) \
(__int64(Instance)<<32 + __int64(&Class::Method))
#define invoke(Func,Method,Class) \
invoke1(Func,(Class*)0)->*invoke2(Func,&Class::Method)
template<class Class>
Class* invoke1(__int64 Func,Class*)
{
return (Class*)(int)(Func>>32);
}
template<class Method>
Method invoke2(__int64 Func,Method)
{
return (Method)(int)Func;
}
------------ USAGE ------------
class B
{
void methodB(int a,float b){}
};
std::map<int, __int64> my_map;
my_map[0] = func(cb,methodB,B);
invoke(my_map[0],methodB,B)(1,2.f);

Calling a C++ function pointer on a specific object instance

I have a function pointer defined by:
typedef void (*EventFunction)(int nEvent);
Is there a way to handle that function with a specific instance of a C++ object?
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne() { handler(1); }
};
class B
{
private:
A a;
public:
B() { a.SetEvent(EventFromA); } // What do I do here?
void EventFromA(int nEvent) { // do stuff }
};
Edit: Orion pointed out the options that Boost offers such as:
boost::function<int (int)> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
Unfortunately Boost is not an option for me. Is there some sort of "currying" function that can be written in C++ that will do this kind of wrapping of a pointer to a member function in to a normal function pointer?
You can use function pointers to index into the vtable of a given object instance. This is called a member function pointer. Your syntax would need to change to use the ".*" and the "&::" operators:
class A;
class B;
typedef void (B::*EventFunction)(int nEvent)
and then:
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne(B* delegate) { ((*delegate).*handler)(1); } // note: ".*"
};
class B
{
private:
A a;
public:
B() { a.SetEvent(&B::EventFromA); } // note: "&::"
void EventFromA(int nEvent) { /* do stuff */ }
};
Run away from raw C++ function pointers, and use std::function instead.
You can use boost::function if you are using an old compiler such as visual studio 2008 which has no support for C++11.
boost:function and std::function are the same thing - they pulled quite a bit of boost stuff into the std library for C++11.
Note: you may want to read the boost function documentation instead of the microsoft one as it's easier to understand
I highly recommend Don Clugston's excellent FastDelegate library. It provides all the things you'd expect of a real delegate and compiles down to a few ASM instructions in most cases. The accompanying article is a good read on member function pointers as well.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
You may find C++ FAQ by Marshall Cline helpful to what you're trying to accomplish.
Read about pointers to members.
To call a method on the derived class, the method has to be declared in the base class as virtual and overriden in the base class and your pointer should point to the base class method. More about pointers to virtual members.
If you're interfacing with a C library, then you can't use a class member function without using something like boost::bind. Most C libraries that take a callback function usually also allow you to pass an extra argument of your choosing (usually of type void*), which you can use to bootstrap your class, as so:
class C
{
public:
int Method1(void) { return 3; }
int Method2(void) { return x; }
int x;
};
// This structure will hold a thunk to
struct CCallback
{
C *obj; // Instance to callback on
int (C::*callback)(void); // Class callback method, taking no arguments and returning int
};
int CBootstrapper(CCallback *pThunk)
{
// Call the thunk
return ((pThunk->obj) ->* (pThunk->callback))( /* args go here */ );
}
void DoIt(C *obj, int (C::*callback)(void))
{
// foobar() is some C library function that takes a function which takes no arguments and returns int, and it also takes a void*, and we can't change it
struct CCallback thunk = {obj, callback};
foobar(&CBootstrapper, &thunk);
}
int main(void)
{
C c;
DoIt(&c, &C::Method1); // Essentially calls foobar() with a callback of C::Method1 on c
DoIt(&c, &C::Method2); // Ditto for C::Method2
}
Unfortunately, the EventFunction type cannot point to a function of B, because it is not the correct type. You could make it the correct type, but that probably isn't really the solution you want:
typedef void (*B::EventFunction)(int nEvent);
... and then everything works once you call the callback with an obhect of B. But you probably want to be able to call functions outside of B, in other classes that do other things. That is sort of the point of a callback. But now this type points to something definitely in B. More attractive solutions are:
Make B a base class, then override a virtual function for each other class that might be called. A then stores a pointer to B instead of a function pointer. Much cleaner.
If you don't want to bind the function to a specific class type, even a base class (and I wouldn't blame you), then I suggest you make the function that gets called a static function: "static void EventFrom A(int nEvent);". Then you can call it directly, without an object of B. But you probably want it to call a specific instance of B (unless B is a singleton).
So if you want to be able to call a specific instance of B, but be able to call non-B's, too, then you need to pass something else to your callback function so that the callback function can call the right object. Make your function a static, as above, and add a void* parameter which you will make a pointer to B.
In practice you see two solutions to this problem: ad hoc systems where you pass a void* and the event, and hierarchies with virtual functions in a base class, like windowing systems
You mention that boost isn't an option for you, but do you have TR1 available to you?
TR1 offers function, bind, and mem_fn objects based on the boost library, and you may already have it bundled with your compiler. It isn't standard yet, but at least two compilers that I've used recently have had it.
http://en.wikipedia.org/wiki/Technical_Report_1
http://msdn.microsoft.com/en-us/library/bb982702.aspx
It's somewhat unclear what you're trying to accomplish here. what is clear is that function pointers is not the way.
maybe what you're looking for is pointer to method.
I have a set of classes for this exact thing that I use in my c++ framework.
http://code.google.com/p/kgui/source/browse/trunk/kgui.h
How I handle it is each class function that can be used as a callback needs a static function that binds the object type to it. I have a set of macros that do it automatically. It makes a static function with the same name except with a "CB_" prefix and an extra first parameter which is the class object pointer.
Checkout the Class types kGUICallBack and various template versions thereof for handling different parameters combinations.
#define CALLBACKGLUE(classname , func) static void CB_ ## func(void *obj) {static_cast< classname *>(obj)->func();}
#define CALLBACKGLUEPTR(classname , func, type) static void CB_ ## func(void *obj,type *name) {static_cast< classname *>(obj)->func(name);}
#define CALLBACKGLUEPTRPTR(classname , func, type,type2) static void CB_ ## func(void *obj,type *name,type2 *name2) {static_cast< classname *>(obj)->func(name,name2);}
#define CALLBACKGLUEPTRPTRPTR(classname , func, type,type2,type3) static void CB_ ## func(void *obj,type *name,type2 *name2,type3 *name3) {static_cast< classname *>(obj)->func(name,name2,name3);}
#define CALLBACKGLUEVAL(classname , func, type) static void CB_ ## func(void *obj,type val) {static_cast< classname *>(obj)->func(val);}