int x = 3;
int main() {
int x = 5;
{
int x = 2;
std::cout << ::x; // ::x - global variable
}
}namespace N {
int f(int x);
}
int N::f(int x) { // Qualified ID
...
}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.
struct A {
struct B {
void F();
};
};Ais an unqualified-id.::Ais a qualified-id but has no nested-name-specifier.A::Bis a qualified-id andA::is a nested-name-specifier.::A::Bis a qualified-id andA::is a nested-name-specifier.A::B::Fis a qualified-id and bothB::andA::B::are nested-name-specifiers.::A::B::Fis a qualified-id and bothB::andA::B::are nested-name-specifiers.
using- механизм для более удобного обращения к неймспейсам- Также можно делать псевдонимы
namespace some_long_name {
namespace another_name {
int foo() {
return 1;
}
}
}
namespace al = some_long_name::another_name;
int main() {
std::cout << al::foo();
}The point of declaration for a name is immediately after its complete declarator and before its initializer...
[3.3.2/1]
#include <iostream>
int foo(int* a) {
*a = 0;
return 1;
}
int main() {
int a /*point of declaration*/ = foo(&a);
std::cout << a << '\n';
const int x = 4;
{
int x[x] /*point of declaration*/ = {1, 2, 3, 4};
std::cout << "x[2] = " << x[2] << '\n';
}
}- For example:
int x = 101;
{
int x = x;
std::cout << x << std::endl; // garbage
}- Above code is equal to the below one:
int x = 101;
{
int x;
x = x; // Self assignment, assigns an indeterminate value.
std::cout << x << std::endl;
}- Because:
int x = x; <--// Now, we have the new `x` which hides the older one,
// ^ // so it assigns itself to itself
// |
// +---// Point of declaration,
// // here compiler knows everything to declare `x`.
// // then declares it.- Also, this example shows the point of declaration for an enumerator
const int x = 12;
{
enum { x = x };
// ^
// |
// +---// Point of declaration
// // compiler has to reach to "}" then
// // there is just one `x`, the `x` of `const int x=12`
}- The enumerator
xis initialized with the value of the constantx, namely12. - Source