kenny@uiucdcsb.cs.uiuc.edu (12/05/86)
Is there any way, in current C++, to take the address of an overloaded member function. I understand that the compiler will be able to determine the type of (&cl::entrypoint) by the type of the receiving pointer in an assignment statement, but there doesn't seem to be any way to do it at present. The closest I came was: ------------------------------------------------------------------------ class testclass { public: testclass& operator- (); testclass& operator- (testclass); testclass (); }; typedef testclass& (*NILADIC) (void*); typedef testclass& (*MONADIC) (void*, testclass); typedef testclass& (*CONSTRUCTOR) (); main () { NILADIC niladic = &testclass :: operator-; MONADIC monadic = &testclass :: operator-; CONSTRUCTOR constructor = &testclass :: testclass; } ------------------------------------------------------------------------ which gives the following: ------------------------------------------------------------------------ "memptrtest.c", line 16: error: cannot deduce type for &overloaded _minus() "memptrtest.c", line 16: sorry, <<cfront 10/10/85>> cannot recover from earlier errors ------------------------------------------------------------------------ and I don't see any obvious way to disambiguate the overloaded operator. Any ideas? I could kludge around it by making a named function that in turn calls the operator, but that's even uglier than the usual pointer-to-entry-function kludge (plus, it hasn't been blessed by Mr Stroustrup). Kevin Kenny UUCP: {ihnp4,pur-ee,convex}!uiucdcs!kenny Department of Computer Science ARPA: kenny@B.CS.UIUC.EDU (kenny@UIUC.ARPA) University of Illinois CSNET: kenny@UIUC.CSNET 1304 W. Springfield Ave. Urbana, Illinois, 61801 Voice: (217) 333-8740
bs@alice.UUCP (12/08/86)
Kevin Kenny writes > Is there any way, in current C++, to take the address of an overloaded > member function. I understand that the compiler will be able to > determine the type of (&cl::entrypoint) by the type of the receiving > pointer in an assignment statement, but there doesn't seem to be any > way to do it at present. There appears to be a bug. Sorry. However, the program below is not legal C++: > The closest I came was: > ------------------------------------------------------------------------ > class testclass { > public: > testclass& operator- (); > testclass& operator- (testclass); > testclass (); > }; > > typedef testclass& (*NILADIC) (void*); > typedef testclass& (*MONADIC) (void*, testclass); > typedef testclass& (*CONSTRUCTOR) (); > > main () { > NILADIC niladic = &testclass :: operator-; > MONADIC monadic = &testclass :: operator-; > CONSTRUCTOR constructor = &testclass :: testclass; > } > ------------------------------------------------------------------------ > which gives the following: > ------------------------------------------------------------------------ > "memptrtest.c", line 16: error: cannot deduce type for &overloaded _minus() > "memptrtest.c", line 16: sorry, <<cfront 10/10/85>> cannot recover from earlier errors > ------------------------------------------------------------------------ > and I don't see any obvious way to disambiguate the overloaded > operator. The problem here is that the testclass defines a unary and a binary minus (not a NILADIC and MONADIC). Remember the implicit argument ``this''. You cannot take a pointer to a member function and stuff it into a plain pointer to function and expect it to work. The correct way of taking the pointers is: class testclass { public: testclass& operator- (); // unary testclass& operator- (testclass); // binary testclass (); }; typedef testclass& (testclass::* UMEM) (); typedef testclass& (testclass::* BMEM) (testclass); main () { UMEM unary = &testclass :: operator-; // testclass::operator-() BMEM binary = &testclass :: operator-; // testclass::operator-(testclass) } Unfortunately, that doesn't work either! It ought to. It will be fixed (but I cannot promise when). > Any ideas? I could kludge around it by making a named function that > in turn calls the operator, but that's even uglier than the usual > pointer-to-entry-function kludge (plus, it hasn't been blessed by Mr > Stroustrup). Yes. The problem is not that the functions involved are operator functions (the problem persists when you rename testclass::operator- to testclass::minus) but that there is a bug in the resolution of pointers to overloaded members. However, the problem can be bypassed by having ``-'' implemented by a friend rather than a member (that is what I usually do - I suppose that is why I did not find the bug): class testclass { public: friend testclass& operator- (testclass); // unary friend testclass& operator- (testclass,testclass); // binary testclass (); }; typedef testclass& (*UNARY) (testclass); typedef testclass& (*BINARY) (testclass,testclass); main () { UNARY unary = &operator-; // operator-(testclass) BINARY binary = &operator-; // operator-(testclass,testclass) } I prefer this solution because if there is a conversion to testclass, say testclass::testclass(int) then it can be applied to a first operand of - as well as the second. Since such a conversion typically ought not be applied in the case of a unary - the unary operator- ought to be a member. Thus the ``ideal'' solution will in many cases be: class testclass { public: testclass& operator- (); // unary friend testclass& operator- (testclass,testclass); // binary testclass (int); }; typedef testclass& (testclass::* UNARY) (); typedef testclass& (*BINARY) (testclass,testclass); main () { UNARY unary = &testclass::operator-; // operator-(testclass) BINARY binary = &operator-; // operator-(testclass,testclass) } As it happens, this too works. PS. The really crude brute force approach also works: class testclass { public: testclass& operator- (); testclass& operator- (testclass); testclass (); }; typedef testclass& (*NILADIC) (void*); typedef testclass& (*MONADIC) (void*, testclass); main () { testclass a; NILADIC niladic = (NILADIC)&a.operator-; MONADIC monadic = (MONADIC)&a.operator-; } Avoid it if you can.