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-8740bs@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.