12

当我编写以下代码时,它会被正确编译和执行:

#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using namespace first; //using derective
  using second::y;
  cout << x << endl;
  cout << y << endl;
  return 0;
}

但是,如果我在 main 函数之外使用指令编写如下,

using namespace first; //using derective
using second::y;
int main () {
  cout << x << endl;
  cout << y << endl;
  return 0;
}

它给出了这个编译错误:

g++     namespace03.cpp   -o namespace03
namespace03.cpp: In function ‘int main()’:
namespace03.cpp:20:11: error: reference to ‘y’ is ambiguous
namespace03.cpp:13:10: error: candidates are: double second::y
namespace03.cpp:7:7: error:                 int first::y
make: *** [namespace03] Error 1

谁能解释为什么 using 指令在内部main和外部使用时表现不同main

4

2 回答 2

11

using-declaration 就是这样,一个声明。main的using second::y;内部类似于y在该范围内声明一个变量,该变量隐藏了全局命名空间范围内的任何其他ys。在全局范围内使用using second::y;时,您没有隐藏任何名称,因为两个ys 在同一范围内。

想象一下您的第一个示例如下所示(请参阅下面的评论以获取解释):

namespace first
{
  int x = 5;
  int y = 10;
}

int main () {
  using namespace first; // This makes first::y visible hereafter
  int y = 20; // This hides first::y (similar to using second::y)
  cout << x << endl;
  cout << y << endl; // Prints 20 
}

然而,第二个例子是这样的:

namespace first
{
  int x = 5;
  int y = 10;
}
using namespace first; // This makes first::y visible in global scope
int y = 20; // This is global ::y
int main () {
  cout << x << endl;
  cout << y << endl; // Error! Do you mean ::y or first::y?
}
于 2013-06-25T21:00:38.353 回答
6

using-declaration 和 using-directive 之间有两个主要区别。

第一个区别:(明显的区别)。

namespace first{

int x=1;
int y=2;
}
using first::x; //using declaration

这将允许您使用x没有命名空间名称的变量作为显式限定符,并注意这不包括y.

namespace first{
int x=1;
int y=2;
}
using namespace first;// using directive

这将允许您使用命名空间内的所有变量,first而不使用命名空间名称作为显式限定符。


第二个区别:(这是你不明白的)。

我将向您解释为什么当您在主函数中同时使用 using-directive 和 using-declaration 时不会出现错误,但是当您尝试在全局命名空间中同时使用它们时会出现编译时错误。

假设我们在全局命名空间中定义了两个命名空间,如下所示:

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}


示例 1:

int main () {    
using namespace first;
using second::y;
  cout << x << endl; // this will output first::x;
  cout << y << endl; // this will output second::y;
  return 0;
}

原因是 using-directiveusing second::y将使您的变量y看起来像是使用范围的局部变量using-directive,在这种情况下,它在 main 函数中使用。而 using 声明using namespace first将使在此命名空间中定义的变量first看起来像是全局变量,并且这仅在使用 using 指令的范围内有效,在这种情况下,它在 main 函数内。

所以如果你应用上面所说的,你就会知道如果你做了这样的事情:

示例2:

 using namespace first;
 using second::y;

 int main () {    
  cout << x << endl; 
  cout << y << endl; // two definitions of y. first::y and second::y 
  return 0;
}

您将收到一个错误,因为两者first::ysecond::y都会表现得好像它们是在全局命名空间中定义的一样,因此您最终将违反单一定义规则。

于 2013-06-25T23:31:04.553 回答