4

I found a problem concerning namespace search. The following simplified code failed to compile:

namespace A {
  namespace B { 
    class Test {
    };
  }
  namespace C {
    namespace B {
      typedef B::Test AnAlias;
    }
  }
}

The compiler complains that Test in namespace A::C::B does not name a type.

The problem seems to be that the compiler sees a namespace B inside namespace C and does not no further search. I would have exspected that he also would look in namespace A (which is a enclosing namespace) and find the B::Test there.

If I rename C::B everything is fine.
If I qualify A::B::Test everything is fine.
If I put the typedef directly in namespace A::C everything is fine.

This behavior was tested with gcc 4.1 and intel 12 compiler. (both for linux).

Are the compilers right?

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • I'm not sure, but shouldn't you do typedef ::A::B::Test AnAlias; to make it works? I think that compiler tries to resolve namespace in your current scope. ::A::B::Test will indicate that you're looking for global scope A::B::Test – Kamil Klimek Feb 02 '12 at 14:53
  • Your forgot to close your namespaces with a `;` . Also, use `typedef typename B::Test AnAlias` – Tom Knapen Feb 02 '12 at 14:54
  • 6
    @TomKnapen: Namespaces don't have to be closed with a semicolon. And `typename` is also not relevant here. – Björn Pollex Feb 02 '12 at 14:56
  • 1
    @TomKnapen You don't close namespaces with a `;`. As for the actual question, it's just not how the name search algorithm is designed. That's all. – Seth Carnegie Feb 02 '12 at 14:56
  • @BjörnPollex why is `typename` not relevant here? Test names a type, which as far as I know, requires to be typedef'd with `typename`? – Tom Knapen Feb 02 '12 at 14:59
  • 2
    @TomKnapen: No it doesn't. `typename` is used to disambiguate the names of dependent types in templates, see [here](http://stackoverflow.com/questions/610245/). – Björn Pollex Feb 02 '12 at 15:01
  • class/struct definitions must be closed with a `;` cause a declaration may follow (heavily used in C) for example: `class A {} a;` – unknownfrog Feb 02 '12 at 15:02
  • typename is required for template dependent names to indicate that a dependant type is meant. As far as I know it is only allowed in that context. – unknownfrog Feb 02 '12 at 15:07
  • @BjörnPollex thank you for the interesting reading, it has definitely enriched my knowledge! – Tom Knapen Feb 02 '12 at 15:10

1 Answers1

5

The B in typdef B::Test resolves to A::C::B. If you're going to reuse the name B, you need to specify it to remove the ambiguity. The compilers are behaving properly. IIRC, names are resolved to the closest declaration to its use or reference. In this case A::C::B is the closest declaration to the typedef.

andand
  • 17,134
  • 11
  • 53
  • 79