Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespace Clashing in C++

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?

like image 390
liori Avatar asked Jul 16 '09 17:07

liori


People also ask

What is the namespace in C?

Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed.

How does the collision be avoided in C++?

Filename collisions are easy to prevent by being systematic: organize your headers so that they mimic your namespaces, e.g. boost::numeric::ublas::vector<> comes from #include <boost/numeric/ublas/vector.

What is name collision in C++?

Similarly, C++ requires that all identifiers be non-ambiguous. If two identical identifiers are introduced into the same program in a way that the compiler or linker can't tell them apart, the compiler or linker will produce an error. This error is generally referred to as a naming collision (or naming conflict).


1 Answers

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.

like image 172
Kirill V. Lyadvinsky Avatar answered Sep 23 '22 19:09

Kirill V. Lyadvinsky