nested namespace declaration

447 views
Skip to first unread message

Sean Middleditch

unread,
Jul 19, 2013, 7:21:17 PM7/19/13
to std-pr...@isocpp.org
We should add a nice namespace shorthand, IMO; see user request for such a feature at http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2286601-nested-namespace-declarations

Basic idea is to make

   namespace A::B::C {
   }

semantically equivalent to

   namespace A { namespace B { namespace C {
   } } }

in every way (lookup, etc.).  Just a shorthand.  It is completely identical and only seeks to avoid excessive bracing and the usual desire of users/editors to indent each level.

If you declare A::B::C and A or A::B does not exist yet, it is declared.  If any of A, A::B, or A::B::C is an existing non-namespace declaration, this declaration is invalid.  That is, you cannot use this syntax to try to declare namespaces inside of class scope or the like, or to hide types or function/variable declarations.

NOT proposing to do this for arbitrary declaration; e.g. the following would still be illegal:

    class A::B::my_class {
    };

Maybe the type declaration is useful to have, but I leave that discussion for another time (it can be added at a later date with no conflict with this proposal).

Magnus Fromreide

unread,
Jul 20, 2013, 3:46:33 AM7/20/13
to std-pr...@isocpp.org
On Fri, 2013-07-19 at 16:21 -0700, Sean Middleditch wrote:
> We should add a nice namespace shorthand, IMO; see user request for
> such a feature
> at http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2286601-nested-namespace-declarations


The case where I have wished for something like this is only marginally
related to the one described above but in the definition of the partial
specialization below

namespace X { namespace Y {

template <class X, int>
struct foo {
int bar() { return 0; }
};

} }

// Lots of code and then this is in into another file

namespace A { namespace B { namespace C {

// Do something

} // namespace C
} // namespace B
} // namespace A

namespace X { namespace Y {

template <>
int foo<::A::B::C::tag,17>::bar() { return 1; }

} }

namespace A { namespace B { namespace C {

// Do something with ::X::Y::foo::bar

...


it would be very nice to be able to define the partial specialization
of ::X::Y::foo<int,17>::bar() right inside the A::B::C namespace as
follows:

template <>
int ::X::Y::foo<int,17>::bar() { return 1; }

or even as

template <>
int ::namespace X::namespace Y::foo<int,17>::bar() { return 1; }

particularly when I have to do it over and over again intermixed with
other code - getting out of the current namespace and into the one I
need for the specialization and then back to where I need the
specialization gets old rather quickly.

On the other hand I can understand if people balks on how the name
lookup rules should look in this case.

/MF

Jonathan Wakely

unread,
Jul 22, 2013, 7:33:14 AM7/22/13
to std-pr...@isocpp.org

Yes, this gets suggested now and then, but noone's ever written a proposal AFAICT.



 

Sean Middleditch

unread,
Jul 22, 2013, 2:41:15 PM7/22/13
to std-pr...@isocpp.org


On Saturday, July 20, 2013 12:46:33 AM UTC-7, Magnus Fromreide wrote:

it would be very nice to be able to define the partial specialization
of ::X::Y::foo<int,17>::bar() right inside the A::B::C namespace as
follows:

template <>
int ::X::Y::foo<int,17>::bar() { return 1; }

or even as

template <>
int ::namespace X::namespace Y::foo<int,17>::bar() { return 1; }

At least in specialization case the namespaces must already have been defined for you to have a template to specialize, so a shorthand without the namespace keyword maybe makes more sense.

Forward declarations are another story.
  namespace X { class Y; }
I'm still uncomfortable with idea of
  class X::Y;
being legal.  Adding in the namespace keyword make it:
  namespace X::class Y;
I don't like that, but not for any reasons I can articulate, so it may just be because it's different and new.

Ville Voutilainen

unread,
Jul 22, 2013, 3:14:15 PM7/22/13
to std-pr...@isocpp.org
On 22 July 2013 21:41, Sean Middleditch <sean.mid...@gmail.com> wrote:
Forward declarations are another story.
  namespace X { class Y; }
I'm still uncomfortable with idea of
  class X::Y;
being legal.  Adding in the namespace keyword make it:

Isn't that already legal?


Sean Middleditch

unread,
Jul 22, 2013, 3:33:55 PM7/22/13
to std-pr...@isocpp.org
On Mon, Jul 22, 2013 at 12:14 PM, Ville Voutilainen
<ville.vo...@gmail.com> wrote:
>
>> Forward declarations are another story.
>> namespace X { class Y; }
>> I'm still uncomfortable with idea of
>> class X::Y;
>> being legal. Adding in the namespace keyword make it:
>
> Isn't that already legal?

The first example, yes, that's what you do today, but not the second.
You can't introduce a definition into a namespace scope without
putting it inside the "namespace X { }" construct. It makes sense to
a degree, as X::Y could be either"
namespace X { class Y; }
or it could be a nested type as in:
struct X { class Y; };
so having X::Y by itself without X being defined already is ambiguous.
Even then, the following is not legal today as I understand (and a
quick test with GCC 4.8 agrees):
namespace X {}
class X::Y; // error: 'Y' in namespace 'X' does not name a type
--
Sean Middleditch
http://seanmiddleditch.com

Ville Voutilainen

unread,
Jul 22, 2013, 3:36:53 PM7/22/13
to std-pr...@isocpp.org
On 22 July 2013 22:33, Sean Middleditch <se...@middleditch.us> wrote:
On Mon, Jul 22, 2013 at 12:14 PM, Ville Voutilainen
<ville.vo...@gmail.com> wrote:
>
>> Forward declarations are another story.
>>   namespace X { class Y; }
>> I'm still uncomfortable with idea of
>>   class X::Y;
>> being legal.  Adding in the namespace keyword make it:
>
> Isn't that already legal?

The first example, yes, that's what you do today, but not the second.
You can't introduce a definition into a namespace scope without
putting it inside the "namespace X { }" construct.  It makes sense to

Both clang and gcc seem to allow it, as long as the namespace already
contains a previous declaration.

 
a degree, as X::Y could be either"
   namespace X { class Y; }
or it could be a nested type as in:
   struct X { class Y; };
so having X::Y by itself without X being defined already is ambiguous.

Sure, that's different.
 
 Even then, the following is not legal today as I understand (and a
quick test with GCC 4.8 agrees):
   namespace X {}
   class X::Y; // error: 'Y' in namespace 'X' does not name a type

Yes, you need to declare Y inside X first. This seems legal:

namespace X {class Y;}
class X::Y {};


Sean Middleditch

unread,
Jul 22, 2013, 3:42:24 PM7/22/13
to std-pr...@isocpp.org
Which is not the same thing at all. That is doing a forward
declaration using the current syntax and then defining the class. You
can't forward declare the type outside of the namespace {} bit. I
used the term "definition" where I should have said "forward
declaration" in my previous message; apologies.
Reply all
Reply to author
Forward
0 new messages