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?
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
}
}
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;
}
Related
I write some header file. I want separately declare the namespaces hierarchy (for clarity), and and then declare functions and classes. For me it looks as a table of contents in the document. It would be very convenient for me: to see the full hierarchy of namespaces in one place. I write this:
// Namespaces hierarchy:
namespace Bushman{
namespace CAD_Calligraphy{}
//...
}
// Declarations of classes and functions
class Bushman::CAD_Calligraphy::Shp_ostream{
public:
explicit Shp_ostream(std::ostream& ost);
};
But MS Visual Studio shouts on such way of creation of the header file. I should write so:
namespace Bushman{
namespace CAD_Calligraphy{
class Shp_istream{
public:
explicit Shp_istream(std::istream& ist);
};
}
}
Why the first variant doesn't work? Is this restriction of the C++, or IDE?
P.S. My additional question is here.
Thank you.
The restriction is in §9/1: "If a class-head-name contains
a nested-name-specifier, the class-specifier shall refer to
a class that was previously declared directly in the class or
namespace to which the nested-name-specifier refers[...]". In
other words, the first appearance of the class name cannot be in
something like Bushman::CAD_Calligraphy::Shp_ostream.
What you can do is add forward declarations in your initial
declaration of the hierarchy:
// Namespaces hierarchy:
namespace Bushman{
namespace CAD_Calligraphy{
class Shp_ostream;
//...
}
//...
}
// Declarations of classes and functions
class Bushman::CAD_Calligraphy::Shp_ostream{
public:
explicit Shp_ostream(std::ostream& ost);
};
Depending on how your headers are organized, this might even be
better from the human point of view: your header starts with
a sort of index of what is defined in it.
To quote the standard: Section 7.3.1.2 point 2:
Members of a named namespace can also be defined outside that
namespace by explicit qualification (3.4.3.2) of the name being
defined, provided that the entity being defined was already declared
in the namespace and the definition appears after the point of
declaration in a namespace that encloses the declaration’s namespace.
namespace Q {
namespace V
void f();
}
void V::f() { /∗ ... ∗/ } // ok.
void V::g() { /∗ ... ∗/ } // Error: g() is not yet a member of V
namespace V
void g();
}
}
namespace R {
void Q::V::g() { /∗ ... ∗/ } // // error: R doesn’t enclose Q
}
So, you could do what you have in your original post, if you declare the class name there:
namespace Bushman{
namespace CAD_Calligraphy {
class Shp_ostream;
...
}
}
That's how C++ works.
It's consistent with other nested declarations: you can't add members to a class from outside the class:
class A
{
};
void A::f() { } // Error!
And you can't add enumerators to an enum from outside:
enum E { E1 = 1, E2 = 2 };
E::E3 = 3; // Error!
You need to "open" the scope and declare the entity inside the scope. Once it's declared you can define it outside that scope, using a nested-name:
class A
{
void f(); // declare
};
void A::f() { } // define
First of all, C++ is not designed to work like that. So it is not a surprise that this is happening.
But, since you're using Visual Studio, you could take advantage of partial classes. Unfortunately, it seems this characteristic is only related to C++/CX so maybe yo won't be able to use it.
You will still need to declare a partial class in your namespace hierarchy, but I guess it could be empty.
To be honest, I haven't used this feature and I don't know how far can it be bent in order to achieve what you want. But you could anyway give it a try.
Remember that this is a Visual Studio extension, so your code won't be cross-platform.
Hope this helps. Somehow.
I am trying to write lines of code fitting under 80 columns maximum. Thus, I wonder if fully qualifying my variable type is really mandatory ? Assuming the following implementation:
//Baz.h
namespace loggingapi {
namespace attributes {
class Baz {};
}} // namespaces
// Bar.h
namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}
class Biz {
int f(Baz* b);
};
} // namespaces
To declare my function parameter type, there are multiple ways ?
a) int f(Baz* b);
b) OR int f(attributes::Baz* b);
c) OR int f(loggingapi::attributes::Baz* b);
d) OR int f(::loggingapi::attributes::Baz* b);
In the list above, which definition(s) is/are clearer/ambiguous for the compilers ?
NOTE: You must assume the namespace/parameter/class/function names CANNOT be shortened in the following implementation.
Variant e ?
namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}
class Biz {
typedef attributes::Baz Baz;
// C++ 11 alternative
// using Baz = attributes::Baz;
int f(Baz* b);
}
} // namespaces
Do not forget what aliasing can do for you...
I would go with the b) variant. My reasons are as follows:
We assume that the developer knows in what namespace he is now. So when looking at the class Biz, the developer should know that this class is in the loggingapi namespace, therefore, there's no need to explicitly state it.
The a) variant, on the other hand, isn't clear enough, because we should indicate that Baz and Biz are actually in different namespaces. Also, it is not going compile, because the compiler will look for Baz in the loggingapi namespace, and it isn't there.
You should choose (b). It's more flexible. If you decide to move or (gasp) cut and paste f and it's related types to a new namespace or project then using (b) ensures that the structure of the declarations remains internally consistent.
You can choose to add, remove or rename outer wrapping namespaces without affecting the enclosed code.
In h-file it is better to use fully qualified names, to prevent possible ambiguity in a client code. In .cpp file you can use short notation, if you prefer this, as long as there is no name clash.
If a compiler has some ambiguity it will definitely report an error.
I believe the question should be with respect to the human reader, which is quite subjective.
The naming convention depends on
Pre-decided coding style
Where you are declaring the function f()
There is no clear choice over another. I would prefer that, if both entities are belonging to same namespace then I will omit at least that part from the name:
namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}
class Biz {
int f(attribute::Baz* b);
}; // ^^^^^^^^^^^^^
}
I sometimes declare classes in nested namespaces and when it comes to defining their member functions, I prefer not to have to qualify each one with these nested namespace names, especially if they are long-ish.
Adding "using namespace " (or, for more precise targetting, "using ::SomeClass") before I define the member functions seems to obviate the need to qualify each definition, but I can't find anywhere in the spec that guarantees this, and I'm worried that it might be a behaviour that only works with GCC. I note that there doesn't appear to be a similar mechanism for skipping the need to add the qualifiers when defining free functions(?).
As an example of what I mean:
Header:
// example.h
namespace SomeNamespace
{
class SomeClass
{
public:
void someMemberFunction();
};
void someFreeFunction();
};
Implementation:
// example.cpp
#include "example.h"
using namespace SomeNamespace;
void SomeClass::someMemberFunction()
{
// OK: seems to define SomeNamespace::SomeClass::someMemberFunction(),
// even though we didn't qualify it with SomeNamespace::
}
void someFreeFunction()
{
// Not what we wanted; declares and defines ::someFreeFunction(), not
// SomeNamespace::someFreeFunction() (quite understandably)
}
int main()
{
SomeClass a;
a.someMemberFunction(); // Ok; it is defined above.
SomeNamespace::someFreeFunction(); // Undefined!
return 0;
}
So my question: is the above way of definining SomeClass::someMemberFunction() legal, and where in the spec is this mentioned? If legal, is it advisable? It certainly cuts down on clutter! :)
Many thanks :)
Perhaps I'm getting this wrong but if you have:
// example.h
namespace SomeNamespace
{
class SomeClass
{
public:
void someMemberFunction();
};
void someFreeFunction();
};
You can also simply write:
#include "example.h"
// example.cpp
namespace SomeNamespace
{
void SomeClass::someMemberFunction()
{
}
void someFreeFunction()
{
}
}
When you define a member-function, the compiler realizes that it is a member-function that must belong to a previously declared class, so it looks that class up, as specified in Section 9.3.5 of the standard:
If the definition of a member function is lexically outside its class
definition, the member function name shall be qualified by its class
name using the :: operator. [Note: a name used in a member function
definition (that is, in the parameter-declaration-clause including
the default arguments (8.3.6), or in the member function body, or, for
a constructor function (12.1), in a mem-initializer expression
(12.6.2)) is looked up as described in 3.4. ] [Example:
struct X {
typedef int T;
static T count;
void f(T);
};
void X::f(T t = count) { }
The member function f of class X is defined in global scope; the
notation X::f specifies that the function f is a member of class X and
in the scope of class X. In the function definition, the parameter
type T refers to the typedef member T declared in class X and the
default argument count refers to the static data member count
declared in class X. ]
Basically, what you are doing is fine. However, there is another (preferable) way to cut down on the clutter when using nested namespaces, or namespaces with long names (or both) - define an alias:
namespace short_name = averylong::nested::namespacename;
Consider the following two statements:
namespace foo = bar;
and
namespace foo {
using namespace bar;
}
Are those two statements equivalent, or are there some subtle differences I'm not aware of?
(Please note that this is not a question about coding style - I'm just interested in C++ parsing).
namespace foo=bar;
This does not affect any name lookup rules. The only affect is to make 'foo' an alias to 'bar'. for example:
namespace bar
{
void b();
}
void f () {
bar::b (); // Call 'b' in bar
foo::b (); // 'foo' is an alias to 'bar' so calls same function
}
The following does change lookup rules
namespace NS
{
namespace bar
{
}
namespace foo {
using namespace bar;
void f () {
++i;
}
}
}
When lookup takes place for 'i', 'foo' will be searched first, then 'NS' then 'bar'.
As you are importing a namespace into another, then yes, it should be equal in that respect. However, the second one also allows for other code to be placed within, so you can also put things which are not part of namespace foo within it. The former merely creates an alias.
Assuming a class called Bar in a namespace called foo, which syntax do you prefer for your source (.cpp/.cc) file?
namespace foo {
...
void Bar::SomeMethod()
{
...
}
} // foo
or
void foo::Bar::SomeMethod()
{
...
}
I use namespaces heavily and prefer the first syntax, but when adding code using the Visual Studio Class Wizard (WM_COMMAND handlers, etc.) the auto-generated code uses the second. Are there any advantages of one syntax over the other?
I would decline the first (edit : question changed, the first is what i prefer too now). Since it is not clear where Bar refers to from only looking at the function definition. Also, with your first method, slippy errors could show up:
namespace bar {
struct foo { void f(); };
}
namespace baz {
struct foo { void f(); };
}
using namespace bar;
using namespace baz;
void foo::f() { // which foo??
}
Because it looks in the current scope (there it is the global scope), it finds two foo's, and tells you the reference to it is ambiguous.
Personally i would do it like this:
namespace foo {
void Bar::SomeMethod() {
// something in here
}
}
It's also not clear from only looking at the definition of SomeMethod to which namespace it belongs, but you have a namespace scope around it and you can easily look it up. Additionally, it is clear now that Bar refers to namespace foo.
The second way you show would be too much typing for me actually. In addition, the second way can cause confusion among new readers of your code: Is foo the class, and Bar a nested class of it? Or is foo a namespace and Bar the class?
I prefer an option not listed:
namespace foo {
void Bar::SomeMethod()
{
...
}
} // foo namespace
Unlike option one, this makes it obvious your code belongs in the foo namespace, not merely uses it. Unlike option two, it saves lots of typing. Win-win.
I'd rather go for the first case, where namespaces are explicitly marked:
namespace TheNamespace {
void TheClass::TheMethod() {
// code
}
}
The reason is that it is clear from that syntax that TheClass is a class and TheNamespace is a namespace (not so obvious by any other names). If the code were
void TheNamespace::TheClass::TheMethod() {
// code
}
then a reader does not clearly see whether TheNamespace is a namespace, or a class with an inside class by the name of TheClass.
class TheClass1
{
class TheClass2
{
void TheMethod();
}
};
void TheClass1::TheClass2::TheMethod() {
// code
}
I tend to avoid the 'using' statement, and even then the example by litb with two classes in two different namespaces will make both the compiler and the programmer confused and should be avoided.
I think it depends on each case. If it's a 3rd party library that's similar to your own code, and you want to avoid confusion in the code, then specifying the full namespace at each occurance may be beneficial. But other than that, less code is generally better (unless it becomes unclear).