Tutorial :Namespace Clashing in C++



Question:

I cannot understand why this piece of code does not compile:

namespace A {          class F {};             // line 2          class H : public F {};  }    namespace B {          void F(A::H x);         // line 7          void G(A::H x) {                  F(x);           // line 9          }  }  

I am using gcc 4.3.3, and the error is:

s3.cpp: In function ‘void B::G(A::H)’:  s3.cpp:2: error: ‘class A::F’ is not a function,  s3.cpp:7: error:   conflict with ‘void B::F(A::H)’  s3.cpp:9: error:   in call to ‘F’  

I think that because in line 9 there is no namespace prefix, F(x) should definitively mean only B::F(x). The compiler tries to cast x into its own superclass. In my understanding it should not. Why does it do that?


Solution:1

That's because compiler will search function in the same namespace its arguments from. Compiler found there A::F identifier but it is not a function. In result you'll get the error.

It is standard behaviour as far as I can remember.

3.4.2 Argument-dependent name lookup When an unqualified name is used as the postfix-expression in a function call (5.2.2), other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and namespace-scope friend function declarations (11.4) not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).

For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). Typedef names and using-declarations used to specify the types do not contribute to this set. The sets of namespaces and classes are determined in the following way...

This rule allows you to write the following code:

std::vector<int> x;  // adding some data to x  //...    // now sort it  sort( x.begin(), x.end() ); // no need to write std::sort  

And finally: Because of Core Issue 218 some compilers would compile the code in question without any errors.


Solution:2

Have you tried using other compilers yet? There is a gcc bug report here which is suspended (whatever that means).

EDIT: After some research, I found this more official bug.


Solution:3

Very strange, I copied and pasted directly to VS 2005 and I get an error, which I expected:

Error 1 error LNK2001: unresolved external symbol "void __cdecl B::F(class A::H)"

Because we haven't actually defined F(x) in namespace B... not sure why Gcc is giving this error.


Solution:4

I just tried compiling it on Visual Studio 2005 and it worked fine. I wonder if it's a broken implementation of Argument Dependent Lookup where the namespace from the arguments was accidentally brought in?


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »