Take the 2-minute tour ×

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?

share|improve this question
add comment

4 Answers

up vote 11 down vote accepted

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.

share|improve this answer
So-called Koenig lookup, in fact, described in section 3.4.2 of the C++ Standard. –  anon Jul 16 '09 at 17:43
Then if VS compiles this, it is a bug? –  liori Jul 16 '09 at 17:45
Could you find a reference to that statement? I've never heard of any rule like that... –  xtofl Jul 16 '09 at 17:50
@Neil, you're right. Added a quote just in case. –  Kirill V. Lyadvinsky Jul 16 '09 at 17:50
@liori, VS compiles this because of Core Issue 218. –  Kirill V. Lyadvinsky Jul 16 '09 at 18:11
add comment

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.

share|improve this answer
This is a minimal example of my own code which does compile on my friend's VS2005. I haven't tested this exact piece though. And... DeusAduro seems to have no problem compiling it on VS2005. –  liori Jul 16 '09 at 17:36
The bug report looks quite like this, though it involves templates, which have a yet different (two-phase) lookup scheme. –  xtofl Jul 16 '09 at 17:47
Note: others report VS2005 to compile this code as expected. I tried Comeau's Test Drive -> success. Only gcc seems to suffer from this, it seems. –  xtofl Jul 16 '09 at 17:51
if jia3ep's answer is correct, and I believe it is, then gcc isn't "suffering", but as usual, VS is non-conforming. –  rmeador Jul 16 '09 at 18:02
@xtofl: At least the bug I mentioned first is available here: gcc.gnu.org/bugzilla/show_bug.cgi?id=25980 and has been marked a duplicate of this bug. –  schnaader Jul 16 '09 at 18:21
show 1 more comment

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.

share|improve this answer
add comment

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?

share|improve this answer
add comment

Your Answer


