Subj : Re: Typecasting question To : borland.public.cpp.borlandcpp From : Greg Chicares Date : Tue Dec 14 2004 09:05 pm On 2004-12-14 5:44 PM, Rick wrote: > I see, thanks for the example! If you don't mind, I have another question > related to this a little bit. Since this is a general C++ question, you might post it to borland.public.cppbuilder.language.cpp where there are more genii in residence. > I'm trying to make function pointers on class > functions but I'm having difficulties. This code for example: > > int (TMyClass::*pt2Member)(float, char, char); > > This function pointer can point to a function (with the suitable arguments) > in class TMyClass. But, what if I don't know which class will use it? The > function could be in TMyClass but I also want it to use for other classes. > In other words, the declaration should not depend on any class. I red > somewhere this wasn't possible at all in C++ but maybe you guys know better If it doesn't depend on any class, then I don't see how can do it. So declare it in a base class, and use it for classes that derive from that base. Here's an example I extracted from a unit test that does lots of other things. The original succeds with gcc-3.2.3, como-4.3.3, and bc-5.5.1 . I tested this extracted version with gcc-3.2.3 and it also does what you'd expect. It works for bc-5.02 as well if you get around that compiler's standard library deficiencies, e.g. by removing "std::" and getting rid of the standard which defines std::endl. #include #include struct base_datum { base_datum() :sane(7) {} virtual ~base_datum() {} // Just to make it polymorphic. virtual void abstract_function() = 0; // Make it abstract too. bool base_function() { std::cout << "base_datum::base_function() called " << sane << std::endl; return true; } int sane; }; struct derived_datum :public base_datum { void abstract_function() {} }; class S { public: S() {} public: // Exposed for testing. derived_datum dd; }; int main() { derived_datum S::* pmd = &S::dd; // base_datum S::* pmdb = &S::dd; // invalid conversion [note 1] S s; derived_datum datum = s.*pmd; dynamic_cast(datum).base_function(); // s["dd"]) --> any_member // &S::dd --> derived_datum S::* bool (derived_datum::*pmf0)() = &derived_datum::base_function; (s.dd.*pmf0)(); bool (derived_datum::*pmf1)() = & base_datum::base_function; (s.dd.*pmf1)(); bool ( base_datum::*pmf2)() = &derived_datum::base_function; (s.dd.*pmf2)(); bool ( base_datum::*pmf3)() = & base_datum::base_function; (s.dd.*pmf3)(); } // note 1: // Contravariance: // 'T Base::*' -> 'T Derived::*' is a standard conversion // 'T Derived::*' -> 'T Base::*' is not. // The latter requires an explicit cast, which must [5.2.9/9] // be a static_cast to map // Derived::*T --> Base::*T // which is what we want to do with the function member. And // 4.11/1 makes // Base::*T --> Derived::*T // a standard conversion that needs no cast. .