Xref: utzoo comp.std.c++:295 comp.lang.c++:9406 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!microsoft!jangr From: jangr@microsoft.UUCP (Jan GRAY) Newsgroups: comp.std.c++,comp.lang.c++ Subject: Re: Using return datum type in function signature Keywords: c++,signature,context-sensitive expressions Message-ID: <57195@microsoft.UUCP> Date: 5 Sep 90 20:25:34 GMT References: <4335@celery34.UUCP> <431@mole-end.UUCP> Reply-To: jangr@microsoft.UUCP (Jan Gray) Distribution: comp Organization: Microsoft Corp., Redmond WA Lines: 66 In article <431@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes: >You've hit upon it, more or less. In many languages (Ada included) >the context can be used to help in disambiguation. C's very flexible >expression syntax and semantics are such that, were C++ to allow such >disambiguation, the rules that would have to be applied would prevent >`ordinary' C things from working correctly. Unfortunately, C++ does occasionally use context to disambiguate, however it doesn't affect the behaviour of "'ordinary' C things". Consider these examples: - Address of overloaded function. void f(); void f(int); void (*pf1)() = &f; void (*pf2)(int) = &f; Here the value of the expression '&f' depends upon the context it appears in. - Multiple conversion functions. class IPI { public: operator int(); operator int*(); }; void fi(int); void fpi(int*); void fipi(IPI); int* foo() { IPI ipi; IPI ipi2 = ipi; // use ipi as an ipi object int i = ipi; // int i = ipi.operator int(); int* pi = ipi; // int *pi = ipi.operator int*(); +ipi; // +(ipi.operator int()); *ipi; // *(ipi.operator int*()); fi(ipi); // fi(ipi.operator int()); fpi(ipi); // fpi(ipi.operator int*()); fipi(ipi); // fipi(ipi); return ipi; // return ipi.operator int*(); } Here the value of the expression 'ipi' varies depending upon its context. Note: this behaviour is not precisely defined in E&S. X3J16 must carefully define disambiguation of multiple possible user-defined conversions. Here's what E&S has to say on the subject: %13.2, p. 326 "User-defined conversions are selected based on the type of variable being initialized or assigned to." But what if no variable is being initialized or assigned to, as in "*ipi", above? %12.3, p. 270 "User-defined conversions are applied only where they are unambiguous." Unfortunately, exactly what is "unambiguous" is ill-defined. In "*ipi", above, the situation is unambiguous because only ipi.operator int*(); works in the immediate context; "ipi.operator int()" cannot be dereferenced. Thus class PCDI { public: operator char*(); operator double*(); operator int*(); }; class PLCS { public: operator long*(); operator char*(); operator short*(); }; PCDI pcdi; PLCS plcs; plcs - pcdi; // plcs.operator char*() - pcdi.operator char*() only conversion to char* of both pcdi and plcs makes a valid expression; so there is no ambiguity!?! >how do you disambiguate? Even if you argue that you are converting the >return values to void , on the basis of what could you prefer one >conversion to void over another? Depends if "operator void()" is defined... :-) Jan Gray uunet!microsoft!jangr Microsoft Corp., Redmond Wash. 206-882-8080