[cfe-dev] "using namespace" seemingly not effective

David Blaikie dblaikie at gmail.com
Sun May 12 09:24:10 PDT 2013


On Sun, May 12, 2013 at 12:47 AM, Florian Weimer <fweimer at redhat.com> wrote:
> clang++ (default flags, trunk version) does not grok the following code:
>
> namespace outer {
>   void f(int &);
>   void g();
>   namespace inner {
>     void f(long &);
>   }
> }
>
> void
> outer::g()
> {
>   using namespace outer::inner;
>   int i;
>   f(i);
>   long l;
>   f(l);
> }
>
> t.cpp:16:3: error: no matching function for call to 'f'
>   f(l);
>   ^
> t.cpp:2:8: note: candidate function not viable: no known conversion from
> 'long' to 'int &' for 1st argument
>   void f(int &);
>        ^
>
> I find this rather odd, considering that there is an explicit "using
> namespace" directive.  I'm not sufficiently familiar with the C++ name
> lookup rules, but I could have understood if f(int &) became invisible.  But
> the other way round is very surprising.

(this isn't really a C++ language support forum, but anyway)

Notice that the second call does work - so clearly something about the
name lookup is working. And the first call that errors points directly
to the candidate you intended to call (via the using directive) but
explains why it can't call that version.

If you remove the namespaces from this example you'll get the same
error, try it & see:

void f(long&);
int main() {
  f(3);
}

& the reason is that the parameter is a long /reference/. References
have to refer to something - and the something you've provided (int i)
is not a long. An int is not a long, though it can be converted to one
- that won't happen implicitly for the purpose of binding a reference
to something, as that would result in rather subtle behavior. If the
temporary created by such a conversion were bound to the reference
then any mutation within 'f' would not be visible in 'i' (because the
mutation would be of the temporary long created by the conversion).
The reference cannot be converted because it is a different thing,
fundamentally - there's no runtime polymorphism here ("int" is not a
subclass of "long" (nor the other way around)).



More information about the cfe-dev mailing list