A point from the ISO C++ draft (n3290): 3.4.3.2/1 Namespace members
A point from the ISO C++ draft (n3290): 3.4.3.2/1 Namespace member开发者_Python百科s
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 andA::
is a nested-name-specifier.::A::B
is a qualified-id andA::
is a nested-name-specifier.A::B::F
is a qualified-id and bothB::
andA::B::
are nested-name-specifiers.::A::B::F
is a qualified-id and bothB::
andA::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;
}
};
精彩评论