可以在两个不同的名称空间中声明相同的实体吗?

时间:2015-07-29 17:34:37

标签: c++ namespaces declaration language-lawyer

我对c ++标准中的§7.3.4/ 6有疑问:

  

如果名称查找找到两个不同的名称声明   名称空间,并且声明不会声明相同的实体   没有声明功能,名称的使用是不正确的。

似乎表明存在在两个不同的名称空间中声明相同实体的情况。否则,不需要措辞“和声明不宣布同一实体”。

此类情况的任何例子?请记住,使用声明不会声明任何实体。它们只是指在其他地方(可能通过其他使用声明间接)完成的实体声明。然而,使用声明将其名称引入声明性区域,但这是另一回事。

还要记住,using-directives也没有声明任何实体。

最后观察到命名空间成员的行外定义(使用限定名称的定义)并未在命名空间中声明任何内容,而是仅在目标命名空间中声明。

3 个答案:

答案 0 :(得分:3)

是的,extern。来自[dcl.link]:

  

函数的两个声明   与C语言链接具有相同的函数名称(忽略限定它的命名空间名称)   出现在不同的命名空间范围内引用相同的函数。 带C的变量的两个声明   具有相同名称的语言链接(忽略限定它的命名空间名称)出现在不同的语言链接中   命名空间范围指的是同一个变量。

例如:

namespace A {
    extern "C" int x;
}

namespace B {
    extern "C" int x;
}

extern "C" {
    int x;
}

namespace D {
    using namespace A;
    using namespace B;
}

A::xB::x(以及::x)都是同一个实体。因此,D::x并非形成错误。

经过进一步反思,使用 using-declaration using-directive 的组合,我们可以提出一个不依赖的简单示例在extern

namespace A {
    int i;   
}

namespace B {
    using A::i;
}

namespace C {
    using A::i;
}

namespace D {
    using namespace B;
    using namespace C;
}

int main() {
    D::i = 4; // name lookup finds `i` declared in two different namespaces,
              // B and C. However, both of those declarations refer to the
              // same entity, A::i
}

答案 1 :(得分:0)

但是使用声明会为实体声明名称。从C ++ 11标准,§7.3.3[namespace.udecl] / 1:

  

using声明在声明区域中引入了一个名称,其中出现了using声明。

     
    

using声明

         
      

using typename opt nested-name-specifier unqualified-id ;
        using :: unqualified-id ;

    
  
     

在using声明中指定的成员名称在using声明出现的声明区域中声明。

答案 2 :(得分:-2)

namespace A{
void fun(){}
}
namespace B{
void fun(){}
}
int main()
{
using namespace A;
using namespace B;
fun()//ambiguous call here because this entity is present in both the namespaces 

}

在上面的代码中,对fun的调用是不明确的,因为查找将无法找到正确的调用乐趣。 第二个例子如下:

namespace N { namespace A {int i;} }

struct A {static int i;};

using namespace N;

int i = A::i; 

在后一种情况下,呼叫是不明确的,因为实体' A'存在于命名空间(N和全局命名空间)中。 希望这会有所帮助