boost & c-style calback issue

Hi,
i'm facing this problem may be someone on the list do have an elegant solution
class A;
class B;
class C {
int operator () (A*,B*)
};
typedef int (*foobar)(A*,B*);
void do_something(foobar cb);
C obj;
do_something(obj); *ERROR*
did try boost::function

Hi,
i'm facing this problem may be someone on the list do have an elegant solution
class A; class B;
class C { int operator () (A*,B*) };
typedef int (*foobar)(A*,B*); void do_something(foobar cb);
C obj; do_something(obj); *ERROR*
Object of type C is not convertible to function pointer type foobar.
did try boost::function
ftor = obj; do_something(ftor); *ERROR* compiler generates in both cases the following error messages cannot convert parameter 2 from 'boost::function<Signature>' to 'int (__cdecl *)(A *,B *)'
with 1> [ 1> Signature=int (A *, B *) 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I can't make the corresponding class B member function static due to side-effects. Any clue how to get rid of this?
You got it backwards - raw function pointer is convertible to boost::function, not the other way around (compiler is trying to tell you exactly that.) Make 'do_something' take boost::function instead. Hope this helps. -- Nikolai

Hi Nikolai, thanks for your speedy reply. Nikolai N Fetissov wrote:
Hi,
i'm facing this problem may be someone on the list do have an elegant solution
class A; class B;
class C { int operator () (A*,B*) };
typedef int (*foobar)(A*,B*); void do_something(foobar cb);
C obj; do_something(obj); *ERROR*
Object of type C is not convertible to function pointer type foobar.
did try boost::function
ftor = obj; do_something(ftor); *ERROR* compiler generates in both cases the following error messages cannot convert parameter 2 from 'boost::function<Signature>' to 'int (__cdecl *)(A *,B *)'
with 1> [ 1> Signature=int (A *, B *) 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I can't make the corresponding class B member function static due to side-effects. Any clue how to get rid of this?
You got it backwards - raw function pointer is convertible to boost::function, not the other way around (compiler is trying to tell you exactly that.) Make 'do_something' take boost::function instead.
The problem is that "do_something" is a legacy code written in plain C and it expect to get a function pointer with the signature typedef int (*foobar)(A*,B*); where A and B are struct. Making the member function that has that signature static helps solve the problem but then we do have undesirable side-effect since this operation should be instance based and not object-bases. May be someone can come out with a better approach?! Thanks Cheers Mike

i'm facing this problem may be someone on the list do have an elegant solution
class A; class B;
class C { int operator () (A*,B*) };
typedef int (*foobar)(A*,B*); void do_something(foobar cb);
C obj; do_something(obj); *ERROR*
Object of type C is not convertible to function pointer type foobar.
did try boost::function
ftor = obj; do_something(ftor); *ERROR* compiler generates in both cases the following error messages cannot convert parameter 2 from 'boost::function<Signature>' to 'int (__cdecl *)(A *,B *)'
with 1> [ 1> Signature=int (A *, B *) 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I can't make the corresponding class B member function static due to side-effects. Any clue how to get rid of this?
You got it backwards - raw function pointer is convertible to boost::function, not the other way around (compiler is trying to tell you exactly that.) Make 'do_something' take boost::function instead.
The problem is that "do_something" is a legacy code written in plain C and it expect to get a function pointer with the signature
typedef int (*foobar)(A*,B*); where A and B are struct.
Making the member function that has that signature static helps solve the problem but then we do have undesirable side-effect since this operation should be instance based and not object-bases. May be someone can come out with a better approach?!
With such restriction I would go with making C a singleton (or pooled object - same idea) and doing something like: class C { public: int DoStuff( A*, B* ); // or op() - doesn't matter static C& GetInstance( /*XXX*/ ); // or pointer private: // singleton stuff ... }; // extern "C" ? int CallbackFunc( A* a, B* b ) { return C::GetInstance( /*XXX*/ ).DoStuff( a, b ); } do_something( CallbackFunc ); This is of course just one way of doing things and very much depends on the context. Generally, you got a subsystem boundary and need to figure out a clean interface. Hope this helps. -- Nikolai

Hi, Nikolai N Fetissov wrote:
Making the member function that has that signature static helps solve the problem but then we do have undesirable side-effect since this operation should be instance based and not object-bases. May be someone can come out with a better approach?!
With such restriction I would go with making C a singleton (or pooled object - same idea) and doing something like:
class C { public: int DoStuff( A*, B* ); // or op() - doesn't matter static C& GetInstance( /*XXX*/ ); // or pointer private: // singleton stuff ... };
// extern "C" ? int CallbackFunc( A* a, B* b ) { return C::GetInstance( /*XXX*/ ).DoStuff( a, b ); }
do_something( CallbackFunc );
This is of course just one way of doing things and very much depends on the context. Generally, you got a subsystem boundary and need to figure out a clean interface.
Your approach is exactly what we don't want, since it makes it an object-based based solution rather than instance-based. We are using a functor (therefor the oprerator()) so that the solution remains instance-based. Like I've said we want to apply it to different instances of C with their own different and non-static member variables. C c1,c2,c3; Did google a bit and one possible solution was boost::function in combination with boost::bind. But I'm not familiar to that ;( Cheers Mike

Michael Bradley Jr:
Did google a bit and one possible solution was boost::function in combination with boost::bind. But I'm not familiar to that ;(
You need to change the foobar in
typedef int (*foobar)(A*,B*);
void do_something(foobar cb);
to boost::function

Making the member function that has that signature static helps solve the problem but then we do have undesirable side-effect since this operation should be instance based and not object-bases. May be someone can come out with a better approach?!
With such restriction I would go with making C a singleton (or pooled object - same idea) and doing something like:
class C { public: int DoStuff( A*, B* ); // or op() - doesn't matter static C& GetInstance( /*XXX*/ ); // or pointer private: // singleton stuff ... };
// extern "C" ? int CallbackFunc( A* a, B* b ) { return C::GetInstance( /*XXX*/ ).DoStuff( a, b ); }
do_something( CallbackFunc );
This is of course just one way of doing things and very much depends on the context. Generally, you got a subsystem boundary and need to figure out a clean interface.
Your approach is exactly what we don't want, since it makes it an object-based based solution rather than instance-based. We are using a functor (therefor the oprerator()) so that the solution remains instance-based.
Like I've said we want to apply it to different instances of C with their own different and non-static member variables.
C c1,c2,c3;
Did google a bit and one possible solution was boost::function in combination with boost::bind. But I'm not familiar to that ;(
boost::bind is very powerful but that won't work against legacy code taking plain function pointer either. My impression is that you are going the wrong way about this. Functors "look" like functions, but underlying mechanism is different. It's not like having operator() makes a class magically "derived" from a function pointer. Unless you control that legacy source code you will need a free function here to take address of. -- Nikolai

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Michael Bradley Jr wrote:
Hi,
i'm facing this problem may be someone on the list do have an elegant solution
This is really not a boost-related problem; this is basic C++.
class A; class B;
class C { int operator () (A*,B*) };
Try making class C look more like this: class C { int operator()(); A aInstance; B bInstance; }; You can then modify the operator() function to use aInstance and bInstance instead of using parameters to pass them in.
typedef int (*foobar)(A*,B*); void do_something(foobar cb);
Just a suggestion - eliminate all typedef statements from your code until you really understand what your code is doing. Typedefs are merely aliases that will add to your confusion.
C obj; do_something(obj); *ERROR*
Yes, this is an error: - 'obj' is an instance of C that knows absolutely nothing about A or B - 'do_something()' is a function that expects a function pointer (with pointer-to-A and pointer-to-B as its parameters) and knows nothing about C
did try boost::function
ftor = obj; do_something(ftor); *ERROR* compiler generates in both cases the following error messages cannot convert parameter 2 from 'boost::function<Signature>' to 'int (__cdecl *)(A *,B *)'
with 1> [ 1> Signature=int (A *, B *) 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I can't make the corresponding class B member function static due to side-effects.
There is no class B member function mentioned anywhere in your sample...
Any clue how to get rid of this?
Thanks in advance Mike
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFIRAah/X5Z5iyVCbERAhaBAJ0dMRBgIGpdsE1gO3WgK7VJ2grAFwCfUA0A 4kCYj9hx6uTEu/xn7Ex2rOc= =8Aik -----END PGP SIGNATURE-----

void do_something(foobar cb); // this function accepts argument
which is a point of function
do_something(obj); // but obj is a function.
i think we should do it like tihs
class A {
};
class B {
};
class C {
public:
int operator () (A*,B*){
cout<<"yes"<
Hi,
i'm facing this problem may be someone on the list do have an elegant solution
class A; class B;
class C { int operator () (A*,B*) };
typedef int (*foobar)(A*,B*); void do_something(foobar cb);
C obj; do_something(obj); *ERROR*
did try boost::function
ftor = obj; do_something(ftor); *ERROR* compiler generates in both cases the following error messages cannot convert parameter 2 from 'boost::function<Signature>' to 'int (__cdecl *)(A *,B *)'
with 1> [ 1> Signature=int (A *, B *) 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I can't make the corresponding class B member function static due to side-effects. Any clue how to get rid of this?
Thanks in advance Mike
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (5)
-
Michael Bradley Jr
-
Nikolai N Fetissov
-
Peter Dimov
-
Rupert Bruce
-
wang wenhua