Why does everybody use unanchored namespace declarations (i.e. std:: not ::std::)?
The practical reason for unanchored namespaces is that one level of namespaces usually is enough. When it isn't, a second level is usually going to be used for implementation details. And finally, even when using multiple levels, they are still usually specified implicitly from root level. ie. even inside namespace ns1
, you'd typically refer to ns1::ns2::foo
instead of ns2::foo
or ::ns1::ns2::foo
.
So, for these three reasons the ::ns1
form is redundant in normal cases. The only case where I'd consider it would be in submissions to Boost, because as a Boost author I won't know where my software will be used.
Is it legal C++ to declare a nested namespace `std`?
In the reserved names
standard 17.4.3.1 (and its sub-paragraphs) I can't find anything that prohibits using std
as a nested namespace name. It's not a macro, it's not in the global namespace, and it doesn't seem to meet any of the "external linkage criteria" that would prohibit it.
It appears to be legal (although as you note extremely inadvisable).
C++: Namespace syntax question
It will work if you put in the ;
after the class definitions. But it will not work in quite the way you expect. First, it tries to figure out what namespace you're talking about. First it will looks for ::Stuff::Stuff
, and when it doesn't find it, it then looks for the namespace ::Stuff
. It finds that namespace, so it then looks in that namespace for Sprite
and finds your class.
If you have an unanchored namespace, it looks for that namespace path in the current namespace, then in the enclosing namespace, then in the enclosing enclosing namespace... etc... until it gets to the top level namespace.
See this question of mine:
- Why does everybody use unanchored namespace declarations (i.e. std:: not ::std::)?
In my opinion, people ought to be a lot more careful than they are about referring to namespaces. Hardly anybody ever uses a root anchored namespace specification, even when they should be because they really do mean a specific absolute namespace and not a name relative to the current namespace.
Here are a couple of interesting cases:
1 namespace Bar {
2
3 class A {
4 };
5
6 } // end namespace ::Bar
7
8 namespace Foo {
9
10 class A {
11 };
12
13 Foo::A joe; // Refers to the A declared on line 10
14
15 namespace Foo {
16 }
17
18 Foo::A fred; // Error, finds ::Foo::Foo and doesn't find A there.
19 ::Foo::A fred; // Works and refers to the A declared on line 10
20
21 Bar::A barney; // Works, and refers to the A declared on line 3
22
23 namespace Bar {
24
25 class A {
26 };
27
28 } // end namespace ::Foo::Bar
29
30 Bar::A wilma; // Works, and refers to the A declared on line 25
31 ::Bar::A betty; // Also works, and refers to the A declared on line 3
32 ::Foo::Bar::A dino; // Also works, and refers to the A declared on line 25
33 } // end namespace ::Foo
When, where and why use namespace when registering custom types for Qt
I'm referring to Qt5 in this answer. Qt4 doesn't go well with this use case.
Data stream operators
Data stream operators are not required for your type if you only intend to use it in signals and slots. They are required if you want to do some serialization.
Pointers, references and values
Qt considers MyClass
and MyClass*
two different unrelated types. You should declare, register and use them separately. Using const MyClass &
argument type is compatible with MyClass
in Qt meta-object system. Note that using MyClass
and MyClass*
meta types simultaneously in one program is unusual and can cause mistakes and confusion. You should choose one of the options and use it throughout the program. Also passing pointers to slots is not recommended because it causes unsolvable ownership problem. So I recommend to use passing by const reference (which sometimes will be converted to passing by value internally in Qt signal-slot system). If MyClass
objects contain massive data, you should implement implicit data sharing using QSharedDataPointer
.
Declaring a meta type
First of all, you always need to declare your meta type:
Q_DECLARE_METATYPE(foo::MyClass)
It works at compile time, so there are no limitations on how you refer to your class. The following code will work as well:
using namespace foo;
Q_DECLARE_METATYPE(MyClass)
Registering a meta type
Now you need to register your classes. Theoretically, you need to specify all strings that you want to use to refer to your type, i.e.:
qRegisterMetaType<foo::MyClass>("MyClass");
qRegisterMetaType<foo::MyClass>("foo::MyClass");
It doesn't matter how you refer to MyClass
in the template argument. The following code will work similarly:
using namespace foo;
qRegisterMetaType<MyClass>("MyClass");
qRegisterMetaType<MyClass>("foo::MyClass");
For example, the "MyClass"
and "foo::MyClass"
strings are used to identify argument types when you refer to your signals and slots like SIGNAL(signal1(MyClass))
.
New signal and slot syntax
If you using new signal slot syntax with pointers to member functions, you need to do only one registration with arbitrary string argument. It seems that it is intended to make it work even without any registrations. This part of the docs instructs to only add Q_DECLARE_METATYPE
, in opposite to this that requires qRegisterMetaType()
. Unfortunately, now in my Qt installation it works only with direct connections. Queued connections still require at least one registration call.
Implicit registration of class without namespace
I was experimenting with some variants of registration in Qt 5.1 and found out that Qt automatically registers aliases without namespace. So if you write
qRegisterMetaType<foo::MyClass>("foo::MyClass");
, Qt will additionally automatically register "MyClass"
alias. So, after executing this statement you will be able to refer to your type as MyClass
and foo::MyClass
. There is no information in the documentation about how Qt handles namespaces. We could assume that this behavior is intended and will not be removed in next versions but I wouldn't rely on that. The following code makes implicit registration obvious:
qRegisterMetaType<foo::MyClass>("foo::MyClass");
qRegisterMetaType<bar::MyClass>("MyClass");
Qt 5.1 says:
QMetaType::registerTypedef: Binary compatibility break -- Type name 'MyClass' previously registered as typedef of 'MyClass' [1030], now registering as typedef of 'bar::MyClass' [1032].
Qt 4.8 works without error (it seems that this behavior is not yet introduced in this version).
Why does import need the project name and not just the object?
It's because your project has a root namespace - you can see this in your project properties. You can delete this in the project properties - this will result in allowing you to simply use the class name from another project. However, namespaces are a good way to organize your classes. In VB, the project defaults to having a root namespace, which you don't see in your code files.
Within your project, since it seems to be all within the same root namespace, you don't have to qualify with the root namespace for code within the root namespace. The "Imports" statements are not within a namespace (only types can be within namespaces) - that's why you have to provide the full qualification there.
Related Topics
C++ Sizeof(Array) Return Twice the Array's Declared Length
What Is the Default Hash Function Used in C++ Std::Unordered_Map
When Should Your Destructor Be Virtual
How to Fix .Pch File Missing on Build
How Would You Implement a Basic Event-Loop
Why Is F(I = -1, I = -1) Undefined Behavior
When to Make a Type Non-Movable in C++11
When to Use Shared_Ptr and When to Use Raw Pointers
Recommended Values for Opencv Detectmultiscale() Parameters
Is There a Name for This Tuple-Creation Idiom
Unique Hardware Id in MAC Os X
How to Detect Ip Address Change Programmatically in Linux
Subtle C++ Inheritance Error with Protected Fields
How to Use Identical Names for Fields and Constructor Parameters