简体   繁体   English

将命名空间的重定义成员放入嵌套的内联命名空间

[英]Redefinition member of the namespace into the nested inline namespace

There is a quote from 7.3.1/8 of N3797: 引用了N3797的7.3.1 / 8:

Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. 内联命名空间的成员可以在大多数方面使用,就像它们是封闭命名空间的成员一样。

Consider the following code snippet: 请考虑以下代码段:

namespace M
{
    int j = 7;
    inline namespace MM
    {
        int j = 8;
    }
}

I think that the example violates the ODR . 我认为这个例子违反了ODR But it is not true and it is compiling successful. 但事实并非如此,它正在编制成功。 Can you explain that behavior? 你能解释一下这种行为吗?

Introduction 介绍

7.3p1 Namespaces [basic.namespace] 7.3p1 命名空间 [basic.namespace]

A namespace is an optionally-named declarative region. 命名空间是可选命名的声明性区域。 The name of a namespace can be used to access entities declared in that namespace; 命名空间的名称可用于访问在该命名空间中声明的实体; that is, the members of the namespace. 也就是命名空间的成员。 Unlike other declarative regions, the definition of a namespace can be split over several parts of one or more translation units. 与其他声明性区域不同,命名空间的定义可以分为一个或多个转换单元的几个部分。

A declared entity inside a namespace belongs to that namespace, ie. 命名空间内的声明实体属于该命名空间,即。 it's a member of that specific namespace, no matter if the namespace is inline or not. 无论命名空间是否内联 ,它都是该特定命名空间的成员。


ODR VIOLATION = N0NE ODR VIOLATION = N0NE

Your example snippet does not violate the ODR , mainly because you have 2 different entities named j ; 您的示例代码片段将不会违反ODR,主要是因为有一个名为2个不同的实体j ;

namespace N {
  int j = 0;            // 1st

  inline namespace M {
    int j = 1;          // 2nd
  }
}

As pointed out further down in [namespace.def]p8 , name lookup in the enclosing namespace will include those found in any inline namespace, but the members of the nested inline namespace are still entities of their own. 正如[namespace.def]p8进一步指出的那样,封闭命名空间中的名称查找将包括在任何inline命名空间中找到的名称,但嵌套内联命名空间的成员仍然是它们自己的实体。

7.3.1p8 Namespace definition [namespace.def] 7.3.1p8 命名空间定义 [namespace.def]

Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lokoup (3.4.2) whenever one of them is, and a using-direction (7.3.4) that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace (7.3.1.1). 具体来说,只要其中一个命名空间及其封闭命隐式插入到封闭的命名空间中,就像未命名的命名空间一样(7.3.1.1)。

Furthermore, each member of the inline namespace can subsequently be explicitly instantiated (14.7.2) or explicitly specialized (14.7.3) as though it were a member of the enclosing namespace. 此外,内联命名空间的每个成员随后可以显式实例化(14.7.2)或显式专用(14.7.3),就像它是封闭命名空间的成员一样。 Finally, lookup up a name in the enclosing namespace via explicit qualification (3.4.3.2) will include members of the inline namespace brought in by the using-directive even if there are declarations of the name in the enclosing namespace. 最后,通过显式限定(3.4.3.2)在封闭命名空间中查找名称将包括using-directive引入的内联命名空间的成员,即使封闭命名空间中存在名称声明。

The added names are not treated as redeclarations of previously declared entities, they are additional names, in a nested declarative region, that are brought into the enclosing namespace during name-lookup. 添加的名称不被视为先前声明的实体的重新声明,它们是嵌套声明性区域中的附加名称,在名称查找期间被带入封闭的命名空间。


Note : Relying on the compiler to issue a diagnostic in terms of ODR-violations is not safe, mainly because the Standard explicitly states that "no diagnostic [is] required" if an application violates the rules set up by [basic.def.odr]. 注意 :依赖于编译器就ODR违规发出诊断是不安全的,主要是因为如果应用程序违反[basic.def.odr].设置的规则,标准明确指出“不需要诊断”。 [basic.def.odr].

Further details are avaiable in a comment by Matthieu M. on this post. Matthieu M.在这篇文章中的评论中提供了更多细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM