can somebody explain me the difference between the following namespace usages:
using namespace ::layer::module;
and
using namespace layer::module;
What causes the additional :: before layer?
There would be a difference if it was used in a context such as:
namespace layer {
namespace module {
int x;
}
}
namespace nest {
namespace layer {
namespace module {
int x;
}
}
using namespace /*::*/layer::module;
}
With the initial :: the first x would be visible after the using directive, without it the second x inside nest::layer::module would be made visible.
A leading :: refers to the global namespace. Any qualified identifier starting with a :: will always refer to some identifier in the global namespace. The difference is when you have the same stuff in the global as well as in some local namespace:
namespace layer { namespace module {
void f();
} }
namespace blah {
namespace layer { namespace module {
void f();
} }
using namespace layer::module // note: no leading ::
// refers to local namespace layer
void g() {
f(); // calls blah::layer::module::f();
}
}
namespace blubb {
namespace layer { namespace module {
void f();
} }
using namespace ::layer::module // note: leading ::
// refers to global namespace layer
void g() {
f(); // calls ::layer::module::f();
}
}
The second case might be X::layer::module where using namespace X has already happened.
In the first case the prefix :: means "compiler, don't be clever, start at the global namespace".
It is called as Qualified name lookup in C++.
It means that the layer namespace being referred to is the one off the global namespace, rather than another nested namespace named layer.
For Standerdese fans:
$3.4.3/1
"The name of a class or namespace member can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that nominates its class or namespace. During the lookup for a name preceding the :: scope resolution operator, object, function, and enumerator names are ignored. If the name found is not a class-name (clause 9) or namespace-name (7.3.1), the program is ill-formed."
Related
Could you explain why namespace look-up fails in that code?
namespace B {
namespace C {
int i;
}
}
namespace A {
namespace B {
void foo() {
// why does not much A::B::C
B::C::i = 3;
}
}
}
Yes, I know ::B::C::i works because we indicates global namespace but I am curious why look-up does not search outside B::C namespaces when we don't use :: before B.
Thanks in advance
Within the namespace ::A::B, the unqualified lookup for B finds the namespace ::A::B rather than finding the namespace ::B. And there is no name ::A::B::C, so the qualified lookup for C within the found ::A::B fails.
Quote from the standard:
A using-directive specifies that the names in the nominated namespace
can be used in the scope in which the using-directive appears after
the using-directive. During unqualified name lookup (3.4.1), the names
appear as if they were declared in the nearest enclosing namespace
which contains both the using-directive and the nominated namespace.
Look at this code:
namespace A {
int fn() { return 1; }
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
Here, before I knew the exact rules of namespaces, I had expected that z will be initialized to 1, as I written using namespace A, so expected that A::fn() will be used. But it is not the case, z will be initialized to 2, as Inner::fn() is called because of the rule I quoted.
What is the rationale behind this behavior: "as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace"?
What would be the cons, if using namespace worked as applying using declarations for everything in that namespace?
Note: this is the related issue that motivated me to ask this question.
A desirable property of a namespace system is that of what I call incremental API compatibility. That is, if I add a symbol to a namespace, then any previously working program should keep working and mean the same thing.
Now, plain C++ with overloads is not incrementally API compatible:
int foo(long x) { return 1; }
int main()
{
foo(0);
}
Now I add the overload int foo(int x) { return 2; } and the program silently changes meaning.
Anyway, when C++ people designed the namespace system they wanted that when incrementing an external API, previously working code should not change the namespace from where the symbol is chosen. From your example, the previous working code would be something like:
namespace A {
//no fn here, yet
}
namespace Inner {
int fn() { return 2; }
namespace B {
using namespace A;
int z = fn();
}
}
And z is easily initialized to 2. Now augmenting namespace A with a symbol named fn will not change the meaning of that working code.
The opposite case does not really apply:
namespace A {
int fn() { return 1; }
}
namespace Inner {
// no fn here
namespace B {
using namespace A;
int z = fn();
}
}
Here z is initialized to 1. Of course, if I add fn to Inner it will change the meaning of the program, but Inner is not an external API: actually, when Inner was written initially, A::fn did already exist (it was being called!), so there is no excuse for being unaware of the clash.
A somewhat practical example
Imagine this C++98 program:
#include <iostream>
namespace A {
int move = 0;
void foo()
{
using namespace std;
cout << move << endl;
return 0;
}
}
int main()
{
A::foo();
return 0;
}
Now, if I compile this with C++11, everything works fine thanks to this using rule. If using namespace std worked as applying using declarations for everything in that namespace, then this program would try to print function std::move instead of A::move.
So i have the following functions:
GraSys::CRectangle GraSys::CPlane::boundingBox(std::string type, std::string color)
{
CRectangle myObject = CRectangle(color);
return myObject;
}
Since boundingBox is part of the namespace GraSys and i have to use it in order to declare this function , why i don't need to do this inside the function?, why can i just use? why does it let me compile with out a problem ?
CRectangle myObject = CRectangle(color);
insted of :
GraSys::CRectangle myObject = GraSys::CRectangle(color);
Hope my question is not confusing.
You're implementing a function that is declared in the namespace of GrasSys. When you're in that function, you use the declaring name space.
For clarity, consider:
namespace GraSys {
class CRectangle { ... };
class CPlane {
... boundingBox(...); ...
}
void example(...) { ... };
}
When you implement boundingBox, you will be in the namespace declared during the declaration of the function, which is GraSys. CRectangle is declared within GraSys, so you can use it directly. Similarly, note that you can directly call functions as well, so in the above code, you can directly call example in your boundingBox implementation.
This is called unqualified name lookup. You can read the complete lookup rules in the C++ standard section 3.4.1 or in more human-readable form here.
Here is an example from the standard, which may be better than verbose explanations:
namespace A {
namespace N {
void f();
}
}
void A::N::f() {
i = 5;
// The following scopes are searched for a declaration of i:
// 1) outermost block scope of A::N::f, before the use of i
// 2) scope of namespace N
// 3) scope of namespace A
// 4) global scope, before the definition of A::N::f
}
using namespace is like add the name space to the global name space (i.e the :: name space). if you do it, from now on the compiler will look for each symbol in all the used name spaces.
Only in case there is ambiguity (mean a symbol with the same name declared in 2 used name spaces, you will be have to use the namespace for it.
namespace A{
void f();
void g();
}
namespace B{
void g();
}
using namespace A;
using namespace B;
A::f(); //always work
f(); //work since it is the only symbol named f
A::g();//always work
B::g();//always work
g();// error since g is ambiguous.
A point from the ISO C++ draft (n3290): 3.4.3.2/1 Namespace members
If the nested-name-specifier of a qualified-id nominates a namespace,
the name specified after the nested-name-specifier is looked up in
the scope of the namespace. If a qualified-id starts with ::, the
name after the :: is looked up in the global namespace. In either
case, the names in a template-argument of a template-id are looked up
in the context in which the entire postfix-expression occurs.
Here can any one explain about the BOLD part .... and from earlier c++03 draft to c++0x draft he added
If a qualified-id starts with ::, the name after the :: is looked up
in the global namespace.
can any one explain with an example program please
::S is a qualified-id.
In the qualified-id ::S::f, S:: is a nested-name-specifier.
In informal terms, a nested-name-specifier is the part of the id that
begins either at the very beginning of a qualified-id or after the initial scope resolution operator (::) if one appears at the very beginning of the id and
ends with the last scope resolution operator in the qualified-id.
Very informally, an id is either a qualified-id or an unqualified-id. If the id is a qualified-id, it is actually composed of two parts: a nested-name specifier followed by an unqualified-id.
Given:
struct A {
struct B {
void F();
};
};
A is an unqualified-id.
::A is a qualified-id but has no nested-name-specifier.
A::B is a qualified-id and A:: is a nested-name-specifier.
::A::B is a qualified-id and A:: is a nested-name-specifier.
A::B::F is a qualified-id and both B:: and A::B:: are nested-name-specifiers.
::A::B::F is a qualified-id and both B:: and A::B:: are nested-name-specifiers.
Another example:
#include <iostream>
using namespace std;
int count(0); // Used for iteration
class outer {
public:
static int count; // counts the number of outer classes
class inner {
public:
static int count; // counts the number of inner classes
};
};
int outer::count(42); // assume there are 42 outer classes
int outer::inner::count(32768); // assume there are 2^15 inner classes
// getting the hang of it?
int main() {
// how do we access these numbers?
//
// using "count = ?" is quite ambiguous since we don't explicitly know which
// count we are referring to.
//
// Nested name specifiers help us out here
cout << ::count << endl; // The iterator value
cout << outer::count << endl; // the number of outer classes instantiated
cout << outer::inner::count << endl; // the number of inner classes instantiated
return 0;
}
EDIT:
In response to your comment, I believe that statement simply means that the arguments of a template are handled w.r.t the context and line by which they are declared. For example,
in f.~foo();, foo is looked up within f., and within the scope of foo<int>, it is valid to refer to it just with with foo.
It is called as Qualified name lookup.
The leading :: refers the global namespace. Any qualified identifier starting with a :: will always refer to some identifier in the global namespace over the same named identifier in local namespace.
namespace A
{
namespace B
{
void doSomething();
}
}
namespace Z
{
namespace A
{
namespace B
{
void doSomething();
}
}
using namespace A::B // no leading :: refers to local namespace layer
void doSomethingMore()
{
doSomething(); // calls Z::A::B::doSomething();
}
}
namespace Z
{
namespace A
{
namespace B
{
void doSomething();
}
}
using namespace ::A::B // leading :: refers to global namespace A
void doSomethingMore()
{
doSomething(); // calls ::A::B::doSomething();
}
}
The bolded text refers to two different situations. The first part is the distinction of using or not using :: as a prefix. When a qualified name starts with :: the exact namespace is checked starting from the empty namespace, while if it is not present, the search will consider nested namespaces:
namespace A {
void f() { std::cout << "::A::f" << std::endl; }
}
namespace B {
namespace A {
void f() { std::cout << "::B::A::f" << std::endl; }
}
void g() {
A::f(); // ::B::A::f
::A::f(); // ::A::f
}
}
The last sentence in the paragraph refers to the specific of template arguments, and it tells you that the lookup will not start in the namespace that the template was declared, but rather in the namespace where it is being instantiated:
struct A {
static void f() { std::cout << "::A::f()" << std::endl; }
};
template <typename T>
void f() {
T::f();
}
namespace N {
struct A {
static void f() { std::cout << "::N::A::f()" << std::endl; }
};
void g() {
f<A>();
}
}
If lookup started in the template namespace, the call f<A>() would refer to f<::A>, but that clause in the standard states the lookup will start inside namespace N (where the entire postfix-expression occurs), and will thus call ::N::A::f().
int a(1);
class someCls {
private:
int a;
public:
// Assigns this->a with the value of the global variable ::a.
void assignFromGlobal() {
a = ::a;
}
};
Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.