3

I don't understand why I get the error "ambiguous call to overloaded function". Before "main", I declared to use namespace "second". My expected output is:

this is the first foo
this is the second foo
this is the second foo

#include <iostream>
using namespace std;

namespace first {
    void foo() {
        cout << "this is the first foo" << endl;
    }
}

namespace second {
    void foo() {
        cout << "this is the second foo" << endl;
    }
}


void foo() {
    cout << "this is just foo" << endl;
}


using namespace second;
void main() {
    first::foo();
    second::foo();
    foo();
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
shir k
  • 107
  • 6
  • 3
    You have two `foos` in your namespace. You should now either use ```::foo()``` or ```second::foo()```. – Steve Mar 24 '18 at 13:31
  • 1
    You expectation is wrong. When you declare`using namespace second` you extend the working namespace with `second`. To clarify from what initial workspace you want to call a function, you should use `::foo`, the global namespace has empty name. – 273K Mar 24 '18 at 13:35
  • 3
    Don't use `using namespace ...` [See this article](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Peter VARGA Mar 24 '18 at 13:36

4 Answers4

3

Before "main", I declared to use namespace "second".

When you do this, second::foo is introduced into the global namespace, then for foo(); both second::foo and ::foo are valid candidates.

You can specify that you want to call the global foo explicitly, i.e.

::foo();

Or use using-declaration inside main() instead of using-directive, e.g.

int main() {
    using second::foo;
    first::foo();
    second::foo();
    foo();
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

The reason this is happening is because of your: using namespace second;

When you do this you qualify the function foo() from the second namespace into the global scope. In the global scope, there exists another function foo() with the exact same signature. Now, your calls to first::foo() and second::foo() are fine. However, when you get to your call to foo(), the compiler doesn't know whether it should call just foo() or second::foo() since they are ambiguous, and at this point they are both in the global namespace.

Carl
  • 2,057
  • 1
  • 15
  • 20
1

Your using namespace second; is precisely the reason you get the error. It practically tells the compiler to treat second::foo as if it was in the global namespace. So now you have two foos there.

By the way, void main is not valid C++. It must be int main.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
1

Firstly, replace void main() { } with

int main() {

 return 0;
}

Secondly, using namespace second; should be inside main() from where you want to call particular namespace, not globally.

Finally, If you are using ::scope resolution operator then you don't have to mention using namespace second in the main(), use either one.

Just do like below

int main() {
        first::foo(); /* first foo will be called */
        second::foo(); /* second foo() will be called */
        foo(); /* global foo() will be called */
        return 0;
}
Achal
  • 11,821
  • 2
  • 15
  • 37