问题
There is from 3.4.1/14:
If a variable member of a namespace is defined outside of the scope of its namespace then any name that appears in the definition of the member (after the declarator-id) is looked up as if the definition of the member occurred in its namespace.
If that name treated as the definition of the member name then what is it point of declaration?
And why the following example will works:
namespace N
{
extern int j;
}
int i = 2;
int N::j = i; //N::j=2
int N::j=i
actual appears into the namespace scope. Hence the declarationint i=2
is not visible for unqualified name lookup. Why does this declaration found?
回答1:
Your question:
int N::j=i
actual appears into the namespace scope. Hence the declarationint i=2
is not visible for unqualified name lookup. Why does this declaration found?
Answer:
Since
i
is not found in theN
namespace, it is looked up in the global namespace. Had ani
been there in theN
namespace, that would have been used to initializeN::j
.
Hope the following program clarifies your doubt.
#include <iostream>
namespace N
{
extern int j;
extern int k;
int x = 3;
}
int x = 2;
int y = 10;
int N::j = x; // N::x is used to initialize N::j
int N::k = y; // ::y is used to initialize N::k
int main()
{
std::cout << N::j << std::endl;
std::cout << N::k << std::endl;
}
Output:
3 10
Update, in response to comment by OP
What the standard is saying is that:
namespace N
{
extern int j;
}
int x = 2;
int N::j = x;
is equivalent to:
namespace N
{
extern int j;
}
int x = 2;
namespace N
{
int j = x;
}
The logic for lookup ofx
is same. If it is found within the same namespace N
, it is used. If x
is not found in namespace N
, it is searched for outward in the enclosing namespaces.
回答2:
You seem to be confused about how name lookup works on a basic level. Maybe a simple example helps:
#include <iostream>
void print(std::string const & s) { std::cout << "Boo: " << s << "\n"; }
namespace Foo
{
std::string message = "Foo";
void action() { print(message); }
}
int main() { Foo::action(); }
Clearly the name print
is visible in the definition of Foo::action
. Names from containing namespaces are visible in contained namespaces. There's nothing unusual about that.
The point of the rule you are quoting, and which R Sahu already demonstrated nicely, is that you can put the definition of a variable elsewhere from its declaration, and in that case any name appearing in the initializer is looked up in the namespace in which the variable is declared. Here's another example:
namespace Foo
{
namespace Bar { int a = 10; }
int b = 20;
extern int c;
}
namespace Bar { int a = -20; }
int b = 5;
int Foo::c = Bar::a + b; // uses Foo::Bar::a and Foo::b, NOT ::Bar::a or ::b
int main() { return Foo::c; } // returns 30
来源:https://stackoverflow.com/questions/23941480/user-declared-namespace-member