|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Generic member functorsI have been trying to use sigc++ library to make a kind of a generic member functor, but I didn't succeed. Basically, I would like to create a functor, to which I would be able assign arbitrary member functions of any class derived from a previously chosen base class. I tried this, but with not much luck. I am attaching a simple example where I would like to show what exactly I mean. I hope that something like this is possible with sigc++. I have also come across several ambiguities with sigc++, which are commented in the source file. I don't understand the behavior of sigc++ there, and I marked these spots, so you can look at them. Thank you all in advance. Get news, entertainment and everything you care about at Live.com. Check it out! /** If you have pkg-config, then you can compile this file for example like this: * c++ -Wall `pkg-config --cflags --libs sigc++-2.0` sigcpp.cpp */ #include <iostream> #include <sigc++/sigc++.h> class Parent { public: int f (int i, double d, char c); }; int Parent::f (int i, double d, char c) { std::cout << "Parent::f" << std::endl; return 0; } class Child : public Parent { public: int g (int i, double d, char c); }; int Child::g (int i, double d, char c) { std::cout << "Child::g" << std::endl; return 0; } typedef sigc::slot<int, Parent *, int, double, char> sp; typedef sigc::slot<int, Child *, int, double, char> sch; typedef sigc::mem_functor3<int, Parent, int, double, char> mfp; typedef sigc::mem_functor3<int, Child, int, double, char> mfch; typedef sigc::mem_functor4<int, Parent, int, double, char, char *> mfp4; typedef sigc::mem_functor4<int, Child, int, double, char, char *> mfch4; int foo (void) { Parent p; Child ch; mfp a_p = sigc::mem_fun(& Parent::f); // <-- This works. a_p(& p, 0, 1.0, 'c'); /// <-- Works a_p(& ch, 0, 1.0, 'c'); /// <-- Works // mfp a_ch = sigc::mem_fun(& Child::g); // <-- Doesn't work, which seems strange. // Compile error: conversion from âsigc::mem_functor3<int, Child, int, double, char>â to non-scalar type âmfpâ requested // mfch b_p = sigc::mem_fun(& Parent::f); // <-- Doesn't work, but this seems correct, because of conversion from Parent to Child. // Compile error: conversion from âsigc::mem_functor3<int, Parent, int, double, char>â to non-scalar type âmfchâ requested mfch b_ch = sigc::mem_fun(& Child::g); // <-- This works. // b_ch(& p, 0, 1.0, 'c'); /// <-- Doesn't work, but this is OK. // Correctly displayed error message: invalid conversion from âParent*â to âChild*â b_ch(& ch, 0, 1.0, 'c'); /// <-- Works sp c_p = sigc::mem_fun(& Parent::f); /// <-- This works c_p(& p, 0, 1.0, 'c'); /// <-- Works c_p(& ch, 0, 1.0, 'c'); /// <-- Works // sp c_ch = sigc::mem_fun(& Child::g); /// <-- This does not work, which seems also strange. // Compile error: invalid conversion from âParent* constâ to âChild*â sch d_p = sigc::mem_fun(& Parent::f); /// <-- This compiles, which is strange. // d_p(& p, 0, 1.0, 'c'); // <-- But this refuses to compile, which is correct. // Correctly displayed error message: invalid conversion from âParent*â to âChild*â d_p(& ch, 0, 1.0, 'c'); // <-- Works sch d_ch = sigc::mem_fun(& Child::g); /// <-- This works // d_ch(& p, 0, 1.0, 'c'); /// <-- Doesn't work, but this is OK. // Correctly displayed error message: invalid conversion from âParent*â to âChild*â d_ch(& ch, 0, 1.0, 'c'); /// <-- Works // I would like to ask for explnation of how to work-around this previously mentioned error: // // Error: invalid conversion from âParent* constâ to âChild*â // // First, why the `const` is added there? /** I agree that this error is in some way reasonable and I know that this usage of functors is not exactly correct. * But is there a correct usage, then? * * What I would like to achieve: * * Have a generic functor, to which I would be able to assign a member function * of arbitrary class derived from the previously specified base class. The only limitations * would be the number of parameters and the type of parameters. I would also like to be able * to alter the number of parameters as well as their type by standard means of sigc++ library. * * The most important is that I would like this functor to behave as the unbound member functor, * so I would be able to choose the instance from which the member function will be called. * * How can I achieve something like this? */ return 0; } int main (int argc, char ** argv) { std::cout << foo() << std::endl; return 0; } _______________________________________________ libsigc-list mailing list libsigc-list@... http://mail.gnome.org/mailman/listinfo/libsigc-list |
|
|
Re: Generic member functorsJinXXXX Kili Billl schrieb:
> Hello, > > I have been trying to use sigc++ library to make a kind of a generic > member functor, but I didn't succeed. > > Basically, I would like to create a functor, to which I would be able > assign arbitrary member functions of any class derived from a previously > chosen base class. I tried this, but with not much luck. I am attaching > a simple example where I would like to show what exactly I mean. > > I hope that something like this is possible with sigc++. > > I have also come across several ambiguities with sigc++, which are > commented in the source file. I don't understand the behavior of sigc++ > there, and I marked these spots, so you can look at them. There are no ambiguities with sigc++. There are templates involved, so you can't e.g. assign a mem_functor typed for a child to a mem_functor typed for a Parent. And I think you are mixing slots and functors... A slot represents a callable entity, no matter what functor is behind. So, a slot is the generic functor you want to have (only knowing about the return type and parameters, but loosing compile-time information about the original functor). What you want to do is the following: <code> Parent p; Child c; sigc::slot<int, Parent*, int, double, char> myclosure; myclosure = sigc::mem_fun(&Parent::f); const int ret1 = myclosure(&p, 0, 1.0, 'c'); myclosure = sigc::mem_fun(&Child::g); const int ret2 = myclosure(&c, 0, 1.0, 'c'); </code> Klaus Triendl _______________________________________________ libsigc-list mailing list libsigc-list@... http://mail.gnome.org/mailman/listinfo/libsigc-list |
|
|
Re: Generic member functors> There are no ambiguities with sigc++. There are templates involved, so > you can't e.g. assign a mem_functor typed for a child to a mem_functor > typed for a Parent. And I think you are mixing slots and functors... I am sorry, you are apparently right. > > A slot represents a callable entity, no matter what functor is behind. > So, a slot is the generic functor you want to have (only knowing about > the return type and parameters, but loosing compile-time information > about the original functor). Thank you very much for explaining this to me. It is precisely what I need. > What you want to do is the following: > > <code> > Parent p; > Child c; > > sigc::slot<int, Parent*, int, double, char> myclosure; > > myclosure = sigc::mem_fun(&Parent::f); > const int ret1 = myclosure(&p, 0, 1.0, 'c'); > > myclosure = sigc::mem_fun(&Child::g); <-- Error line > const int ret2 = myclosure(&c, 0, 1.0, 'c'); > </code> > > > Klaus Triend Does this code compile for you? I just did copy and paste and tried to compile the above code. The result was: error: invalid conversion from ‘Parent* const’ to ‘Child*’ This is the same error I described before in the attached file. So, if this is the right way to cope with my problem, why it refuses to compile? But anyway, thank you for a brief and valuable response. Now I at leas understand better what is what ... See all the ways you can stay connected to friends and family _______________________________________________ libsigc-list mailing list libsigc-list@... http://mail.gnome.org/mailman/listinfo/libsigc-list |
|
|
Re: Generic member functorsJinXXXX Kili Billl schrieb:
>> <code> >> Parent p; >> Child c; >> >> sigc::slot<int, Parent*, int, double, char> myclosure; >> >> myclosure = sigc::mem_fun(&Parent::f); >> const int ret1 = myclosure(&p, 0, 1.0, 'c'); >> >> myclosure = sigc::mem_fun(&Child::g); <-- Error line >> const int ret2 = myclosure(&c, 0, 1.0, 'c'); >> </code> > > Does this code compile for you? I just did copy and paste and tried to > compile the above code. The result was: > > error: invalid conversion from ‘Parent* const’ to ‘Child*’ Sorry, my fault, I didn't try to compile it. > So, if this is the right way to cope with my problem, why it refuses to > compile? Because in the end the slot must call the functor stored in the slot (the functor that you assign to the slot). The function slot4<int, Parent*, int double, char>::call_it() calls the mem_functor3<int, Child*, int, double, char> with the parameter types (int, Parent*, int, double, char) - Parent* is not convertible to Child* or Child&. You have 2 possibilities: 1) make g() [pure] virtual in Parent to get polymorphic runtime behaviour. If you need to be totally flexible about the object instance during runtime then this is the right solution. 2) Rather use mem_fun() to bind the object instance than specifying the instance when calling the slot. If you can decide already at compile time which object instance to use then you can use this solution. Here is some code to show what I mean: 1) <code> class Parent { public: int f(int, double, char) { return 0; } virtual int g(int, double, char) = 0; }; class Child: public Parent { public: // virtuals from Parent virtual int g(int, double, char) { return 0; } }; // somewhere else: Parent p; Child c1, c2; sigc::slot<int, Parent*, int, double, char> myclosure; myclosure = sigc::mem_fun(&Parent::f); // call p->f() myclosure(&p, 0, 1.0, 'c'); myclosure = sigc::mem_fun(&Parent::g); // call c1->g() myclosure(&c1, 0, 1.0, 'c'); // call c2->g() myclosure(&c2, 0, 1.0, 'c'); </code> 2) <code> class Parent { public: int f(int, double, char) { return 0; } }; class Child: public Parent { public: int g(int, double, char) { return 0; } }; // somewhere else Parent p; Child c1, c2; sigc::slot<int, int, double, char> myclosure; // call p->f() myclosure = sigc::mem_fun(&p, &Parent::f); myclosure(0, 1.0, 'c'); // call c1->g() myclosure = sigc::mem_fun(&c1, &Child::g); myclosure(0, 1.0, 'c'); // call c2->g() myclosure = sigc::mem_fun(&c2, &Child::g); myclosure(0, 1.0, 'c'); </code> Klaus _______________________________________________ libsigc-list mailing list libsigc-list@... http://mail.gnome.org/mailman/listinfo/libsigc-list |
| Free embeddable forum powered by Nabble | Forum Help |