用户声明的命名空间成员

User-declared namespace member

本文关键字:成员 命名空间 声明 用户      更新时间:2023-10-16

从3.4.1/14开始:

如果命名空间的变量成员在作用域之外定义的定义中出现的任何名称成员(在declarator-id之后)被查找,就像成员发生在其命名空间中。

如果该名称被视为成员名的定义,那么它的声明点是什么?

以及为什么下面的例子可以工作:

namespace N 
{
    extern int j;
}
int i = 2;
int N::j = i; //N::j=2

int N::j=i实际出现在命名空间作用域中。因此,声明int i=2对于非限定名称查找是不可见的。为什么找到这个声明?

你的问题:

int N::j=i实际出现在命名空间作用域中。因此,声明int i=2对于非限定名称查找是不可见的。为什么发现了这个声明?

答:

由于iN命名空间中找不到,所以它在全局命名空间中查找。如果N名称空间中存在i,则可以使用它来初始化N::j

希望下面的节目能澄清你的疑问。

#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;
}
输出:

<>之前3.10之前

更新,回应OP

标准的意思是:

namespace N 
{
   extern int j;
}
int x = 2;
int N::j = x;

等价于:

namespace N 
{
   extern int j;
}
int x = 2;
namespace N 
{
   int j = x;
}

查找x的逻辑是相同的。如果在同一个命名空间N中找到它,则使用它。

如果在命名空间N中没有找到x,则在封闭的命名空间中向外搜索。

您似乎对名称查找在基本级别上的工作方式感到困惑。也许一个简单的例子会有所帮助:

#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(); }

显然print这个名字在Foo::action的定义中是可见的。来自包含名称空间的名称在包含的名称空间中是可见的。这没什么不寻常的。

您引用的规则的要点是,R Sahu已经很好地演示了,您可以将变量的定义放在其声明的其他地方,在这种情况下,在初始化器中出现的任何名称都将在声明变量的命名空间中查找。下面是另一个例子:

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