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. 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; }