Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Monday, May 08, 2006

Overload resolution doesn't choose between names from different scopes.

Take this code example :

template
class Base
{
protected:
Notify(T& msg);

};

struct msgA {};
struct msgB {};

class Impl : public Base, public Base
{
void Do()
{
msgA a;
Notify(a); // <----- AMBIGUOUS call } } ; When compiled with Comeau online compiler, yeilds the following error:
Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 5: error: omission of explicit type is nonstandard ("int"
assumed)
Notify(T& msg);
^

"ComeauTest.c", line 17: error: "Base::Notify [with T=msgA]" is ambiguous
Notify(a); // <----- AMBIGUOUS call ^ 2 errors detected in the compilation of "ComeauTest.c".
This error is a result of disambiguity rule that C++ compiler employs when resolve overloaded names from different scopes. Although both names are visible at the point of the statement, the rule says overload resolution cannot choose between names from different scopes. Thus the compile error. A simple solution is to pull in names from both scopes into class Impl by using declarations.

With very few exceptions, name lookup must resolve to a set of names in a single scope. The major exception is when ADL is involved, but ADL only applies to namespaces which are searched, not base classes.