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