31

I am confused what to do when having nested namespaces and declarations of objects.

I am porting some code that links against a static library that has a few namespaces.

Example of what I am talking about:

namespace ABC {

    namespace XYZ {

        //STUFF
    }
}

In code what do I do to declare an object that is in namespace XYZ?

if I try:

XYZ::ClassA myobject;

or:

ABC::XYZ::ClassA myobject;

or:

ABC::ClassA myobject;

I get

does not name a type

errors, even though ClassA definitely exists.

What is proper here?

nonsensickle
  • 4,438
  • 2
  • 34
  • 61
jDOG
  • 1,191
  • 5
  • 12
  • 13
  • 3
    I'd say - don't use nested namespaces, keep your namespace scheme as simple as possible. –  Jul 07 '10 at 21:56
  • 1
    What you tried is obviously correct. Perhaps you mistyped a namespace/class in your real code ? You may also check the **character case** (this is a common mistake). – ereOn Jul 07 '10 at 21:57
  • 1
    Just making sure... You do know declaring a new class within the nested name spaces is different than referencing an object declared in an external library from within them. – Jay Jul 07 '10 at 22:21
  • @Neil +1. Using nested namespaces for organizational purposes can lead to a lot more headaches than it's worth (ADL-related along with syntactical burden). I'd suggest sticking to them strictly for avoiding name clashes and stick to as few as possible. Unless you're working in a very large team, one namespace should suffice for a project. – stinky472 Jul 08 '10 at 00:10
  • Agree with anon, keep it flat: http://www.adamjamesnaylor.com/2012/10/23/Nested-Namespaces-In-C.aspx – Adam Naylor Oct 26 '12 at 10:51
  • 2
    The correct method is `ABC::XYZ::ClassA`. If that's not working, the problem is something else. – GManNickG Jul 07 '10 at 21:48
  • @AdamNaylor, your link to your own site is now broken! – Gui Lima Dec 01 '15 at 19:44

2 Answers2

47

It depends on the namespace you already are:

If you're in no namespace or another, unrelated namespace, then you have to specify to whole path ABC::XYZ::ClassA.

If you're in ABC you can skip the ABC and just write XYZ::ClassA.

Also, worth mentioning that if you want to refer to a function which is not in a namespace (or the "root" namespace), you can prefix it by :::

Example:

int foo() { return 1; }

namespace ABC
{
  double foo() { return 2.0; }

  void bar()
  {
    foo(); //calls the double version
    ::foo(); //calls the int version
  }
}
talonmies
  • 70,661
  • 34
  • 192
  • 269
ereOn
  • 53,676
  • 39
  • 161
  • 238
4

If myobject is declared in that namespace and you want to declare it again (for defining it), you do it by prefixing its name, not its type.

ClassA ABC::XYZ::myobject;

If its type is declared in that namespace too, you also need to prefix the name of the type

ABC::XYZ::ClassA ABC::XYZ::myobject;

It's rarely needed to redeclare an object like that. Often the first declaration of an object is also its definition. If you want to first declare the object, you have to do it in that namespace. The following declares and defines "myobject"

namespace ABC {
  namespace XYZ {
    ClassA myobject;
  }
}

If you have defined in object like this, you refer to it by saying ABC::XYZ. You don't have to "declare" that object somehow in order to use it locally

void f() {
  ABC::XYZ::myobject = someValue;

  // you *can* however use a using-declaration
  using ABC::XYZ::myobject;
  myobject = someValue;
}
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • "Often the first declaration of an object is also its definition" This seems to be wrong. If you want to declare some object in a header file it should not be defined there. Otherwise if there are 2 cpp files that include this header, and we will compile and try to link these cpp files, the linker will return an error about duplicated definition. If the second code snippet is about to be in a header, it should be `namespace ABC{ namespace XYZ{ extern ClassA myobject;}}` and then in a corresponding cpp file there should be `ClassA ABC::XYZ::myobject;` (if ClassA is not in a namespace) – Number47 Mar 22 '14 at 13:26
  • @Number47 why is it wrong? I did not say "All declarations of objects are definitions", which you seem to assume me to have. – Johannes Schaub - litb Mar 22 '14 at 13:40
  • @Johnnes I did not say that "In all cases it is wrong". But seriously. If we are talking about things like `namespace ABC {...}`, then it is very very likely that we are about header files (am I wrong?). But it is a bad practice to put something like `ClassA myobject;` in a header as it may cause linker errors, as I pointed out. So in the 3'rd snippet -- I'm sorry, in the previous post it should be also 3'rd -- there should be `extern ClassA myobject;` or there should be a note that this snippet is about to be used in cpp files, not in headers. In other way we may misguide our readers. :) – Number47 Mar 22 '14 at 15:53
  • 1
    @Number47 I don't know whether you are wrong (I haven't made a survey on existing coding guidelines), but I very much think you are wrong. My cpp files use namespaces aswell, rather than repeating explicit qualification on the names each time again when defining entities of that namespace, and I won't be surprised if many other programmers do alike. – Johannes Schaub - litb Mar 22 '14 at 16:37
  • Anyway, the issue with multiply defining things is totally orthogonal to this question. I could aswell put a note for my last snippet and say "This function should not be put into a header or it should be a member function, because it is not explicitly declared inline". IMO it'll be noise. – Johannes Schaub - litb Mar 22 '14 at 16:40
  • I'm glad that you made the remark, so that other people who use a coding guideline that matches yours will know it belongs into a cpp file. – Johannes Schaub - litb Mar 22 '14 at 16:45
  • @Johnnes you are right! I did little too much "compressing" to make it in the characters limit. What I mean is that, in this case your answer suggests that the namespace-nested definition is a part of a header. If it would be a part of cpp file and it would be a declaration and a definition as you mentioned, then it could just look like `namespace { ClassA myobject; }`. Or at least I see no reason to put `ClassA myobject;` in a double namespace then (except some very specific situation). – Number47 Mar 24 '14 at 08:11
  • @Number47 if the header said `namespace ABC { namespace XYZ { extern ClassA myobject; } }` then the cpp file needs the same namespaces aswell. – Johannes Schaub - litb Mar 24 '14 at 09:28