用户声明的命名空间成员

时间:2014-05-29 19:31:51

标签: c++ namespaces

从3.4.1 / 14开始:

  

如果命名空间的变量成员定义在范围之外   它的命名空间然后出现在定义中的任何名称   成员(在声明者身份之后)被查找,就像定义一样   该成员发生在其名称空间中。

如果该名称被视为成员名称的定义,那么宣言的意义何在?

以下示例为什么会起作用:

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

int N::j=i实际出现在命名空间范围内。因此,对于非限定名称查找,声明int i=2不可见。 为什么要发布此声明?

2 个答案:

答案 0 :(得分:3)

你的问题:

  

int N::j=i实际出现在命名空间范围内。因此,对于非限定名称查找,声明int i=2不可见。为什么要发现这个声明?

答案:

  

由于i命名空间中找不到N,因此会在全局命名空间中查找它。如果i命名空间中有N,则会用于初始化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中找到它,则使用它。如果在命名空间x中找不到N,则会在封闭的命名空间中向外搜索它。

答案 1 :(得分:1)

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

#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