5

In the code below, it looks quite obvious that the function definition for myFn with two arguments should come from namespace N. But the compiler fails to compile it. Is it a compiler (g++ 8.3) limitation, or imposed by the C++ standard?

    #include <bits/stdc++.h>

    using namespace std;

    namespace N
    {
      // Same name function exists in class A
      void myFn(int a, int b)
      {
        cout << a << ' ' << b << endl;
      }
    }

    using namespace N;
    class A {
      public:
        void myFn(int a)
        {
    #ifdef FINE
          // Explicitly specify where should myFn definition come from
          N::myFn(a, a);
    #else
          myFn(a, a);
    #endif
        }
    };

    int main()
    {
      A a;
      a.myFn(3);
      return 2;
    }
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458

1 Answers1

6

It's intended. Name lookup stops at the scope where the name is found. The mechanism makes sure your code behaves the same even if functions are added or removed from the enclosing scopes.

Otherwise, changing N's members would risk breaking enclosed classes and namespaces. Consider the potential disasters if one adds a free function that is a better match in overload resolution compared to another class member. If it wasn't ignored, the behavior of the class could change by accident!

This example should illustrate the issue:

namespace ns {
  // void foo(int) { std::terminate(); }
  struct C {
      void foo(char) {}
      C() {
          foo(0);
      }
  };
}

Under the current rules, uncommenting foo will have no adverse effects. But if name lookup did consider it, because 0 is an int and must be converted to a char, constructing a C would abort the program! That's drastic and easy to spot. But in a real 100M LOC program, misbehaving name lookup could cause bugs that are much more sinister and harder to catch.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • And speaking of real production quality code, please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h), and especially couple it with [Why is “using namespace std” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – StoryTeller - Unslander Monica May 16 '19 at 05:27