How to overload operator ->* in C++
Is there a way to overload ->*
for use with a smart-pointer-like object? Below is what I would like to do. For simplicity I'm not using templates (I'll get to that once I have it working for a single fixed class). I can get it to work with pointers to data members, but I can't seem to get it right for pointers to member functions. For the time being, I'm willing to settle for an overload that only works for member functions (and not for data members). I'm even willing to settle for an overload that only accepts pointers to member functions with a single fixed prototype (such as void func()
).
struct MyObject
{
void MyMethod() {}
};
struct MySmartPtr {
MyObject *p;
// What should the prototype and function body be?
// ??? operator->*(????) { ???? }
};
void MyFunc()
{
MyObject obj;
MySmartPtr obj_ptr;
obj_ptr.p = &obj;
void (MyObject::* member_func_ptr)() =开发者_Python百科 &MyObject::MyMethod;
// Now call obj.MyMethod() through the "smart pointer"
(obj_ptr->*member_func_ptr)();
}
Please don't offer me workarounds (e.g., overload *
and do (*obj_ptr.*member_func_ptr)()
). I want ->*
to work as indicated in the code snippet.
Have a look at this article by Scott Meyers. It's quite old, but the only resource discussing overloading ->*
that I know of.
Note that the standard library's iterator and smart pointer types don't overload ->*
. I don't know the reasons, but I suspect it's because that operator rarely ever used, is a lot of hassle to implement, and it's easy to work around it. Anyway, since the standard library doesn't support it, your users won't expect it to work either.
http://codepad.org/yl3Ghwab
#include <stdio.h>
struct OBJ {
typedef void (OBJ::*Met)(void);
void met( void ) {
printf( "Method call!\n" );
}
};
struct POBJ {
OBJ* p;
typedef void (*fun)(void);
static void nop( void ) {}
fun operator->*( OBJ::Met m ) {
printf( "operator ->* !\n" );
// return fun(p->*m); // works in gcc
(p->*m)();
return nop;
}
};
int main( void ) {
OBJ obj;
OBJ* pobj = &obj;
POBJ p; p.p = &obj;
OBJ::Met met = &OBJ::met;
(pobj->*met)();
(p->*met)();
}
See http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B for prototypes
I'll give it a shot with C++0x: variadic templates, bind and function. I guess it should be possible to port it to boost:
#include <iostream>
#include <functional>
struct S
{
void f()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<class C>
struct PMFSmartPtr
{
C *p;
template<typename C1, typename R, typename... P>
std::function<R(P...)> operator->*(R (C1::*pmf)(P...))
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
return(std::function<R(P...)>(std::bind(pmf, p)));
}
};
int main()
{
PMFSmartPtr<S> x;
void (S::*pmf)() = &S::f;
(x->*pmf)();
return(0);
}
Tried on g++ 4.4.4 and works for functions not taking any arguments, for 1 argument member function compilation fails but I do not know if this is my fault or compiler or libstdc++ issue...
精彩评论