4

Why does using ::foo declaration below hide all other foo functions?

#include <iostream>

void foo(double) { std::cout << "::foo(double)" << std::endl; }

struct A {
  void foo(float) { std::cout << "A::foo(float)" << std::endl; }
  void foo(int) { std::cout << "A::foo(int)" << std::endl; }
  void foo() { std::cout << "A::foo()" << std::endl; }
};

struct B : A {
  using A::foo;
  void foo(int) { std::cout << "B::foo(int)" << std::endl; }
  void foo() { std::cout << "B::foo()" << std::endl; }

  void boo() {
    using ::foo;
    foo(1.0);
    foo(1.0f);
    foo(1);
    foo();
  };
};

int main() {
  B b;
  b.boo();
  return 0;
}
Blaz Bratanic
  • 2,279
  • 12
  • 17
  • It's the same ADL lookup thing used for `std::swap` in copy-swap idiom. http://stackoverflow.com/questions/4782692/what-does-using-stdswap-inside-the-body-of-a-class-method-implementation-mea – Brandon Apr 14 '14 at 19:46
  • ok, but why is B::foo() inaccessible? – Blaz Bratanic Apr 14 '14 at 19:47
  • 1
    @BlazBratanic It's not, have you tried `B::foo()`? – yizzlez Apr 14 '14 at 19:50
  • You are right. However, why do i need to explicitly specify which foo function? In this case the whole point of `using` declaration is lost since i could also call `::foo(1.0)`, `A::foo(1.0f)`, etc.. – Blaz Bratanic Apr 14 '14 at 19:54
  • I think you need to also do `using B::foo;` – Deduplicator Apr 14 '14 at 20:00
  • `using` is a *convenience*. When you have conflicts or need to specify scope, don't do it! And really, what is the point of `using ::foo;` other than to make `foo` be `::foo`? – crashmstr Apr 14 '14 at 20:00
  • 1
    @crashmstr: Might work for this case, but try that with enough templates, when you really want the compiler to choose. – Deduplicator Apr 14 '14 at 20:01

1 Answers1

2

Any declaration of a function in an inner scope hides all declarations of functions with the same name in the outer scope.

You declared in the block scope of function boo function ::foo

  void boo() {
    using ::foo;
    foo(1.0);
    foo(1.0f);
    foo(1);
    foo();
  };

It hides all functions with the same name in enclosing scopes.

More precisely. According to the C++ Standard

13 Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region (3.3) also apply to using-declarations

Or maybe it would be better to cite the following quote from the C++ Standard

1 A using-declaration introduces a name into the declarative region in which the using-declaration appears.using-declaration:The member name specified in a using-declaration is declared in the declarative region in which the using-declaration appears.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335