c++ [namespace.memdef]/1的新措辞

23c0lvtd  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(114)

我相信[namespace.memdef]/1的新措辞试图解释命名空间X中的两个声明using M::g;void g();之间的冲突,但我无法理解这个新措辞和所提到的冲突之间的关系。
命名空间N中的声明(不包括嵌套作用域中的声明),其 declarator-idunqualified-id([dcl.meaning]),whose class-head-name(子句[类])或 enum-head-name([dcl.enum])是一个 identifier,或者其 elaborated-type-specifier 的格式为 class-keyattribute-specifier-seqoptidentifier([dcl.type.elab])或 * opaque-enum-declaration*,声明(或重新声明)其 unqualified-ididentifierN的成员。[注意:模板的显式示例化([temp.explicit])或显式专门化([temp.expl.spec])不引入名称,因此如果主模板在内联名称空间中声明,则可以在封闭名称空间集合的成员中使用 unqualified-id 进行声明。

namespace X {
  void f() { /* ... */ }        // OK: introduces X​::​f()

  namespace M {
    void g();                   // OK: introduces X​::​M​::​g()
  }
  using M::g;
  void g();                     // error: conflicts with X​::​M​::​g()
}
  • 结束示例]
    即使当我看到DR 1838(可能是这一段变化的起源)时,我也无法理解以下句子(重点是我的):
    当一个实体在内部命名空间中声明但没有定义,而是通过外部命名空间中的 using-declaration 声明时,该标准并不清楚会发生什么,并且具有该名称的实体的definition作为 unqualified-id 出现在外部命名空间中。这是内部命名空间实体的合法定义吗?如果定义使用 qualified-id,或者该定义是外部命名空间的成员,因此与 using-declaration 冲突?在处理此类定义方面存在实现分歧。
    这句话后面的例子与[namespace.memdef]/1段落中的例子完全相同。我突出显示了上面的单词definition,因为在提到的例子中没有函数X::g()的定义。我错过了什么?
yhxst69z

yhxst69z1#

引用的段落表明,由于外部void g();使用 unqualified-id 作为其 declarator-id,因此它将g声明为外部命名空间的成员,即X
C17 [namespace.udecl]/14也声明如下:
如果命名空间作用域或块作用域中的函数声明与 using-declaration 引入的函数具有相同的名称和相同的parameter-type-list(11.3.5),并且声明不声明相同的函数,则程序是病态的。
问题1838解决方案背后的思想是,你现在有一个g的声明,作为X的成员,但是也有一个由using-declaration引入的g,它是X::M的成员,它们有相同的名字和相同的参数类型列表,但是它们不是相同的函数,所以违反了这个规则,并且程序是病态的。
我不确定即使在这个变化之后,措辞是否完全清楚;我们怎么知道这两个g真的不是同一个函数呢?根据C
17 [basic.link]/9,
相同(第6条)且在不同作用域中声明的两个名称应表示相同的变量、函数、类型、模板或命名空间,如果

  • 两个名称具有外部链接,或者两个名称具有内部链接并且在同一翻译单元中声明;和
  • 两个名称都引用同一命名空间的成员或同一类的成员(不是通过继承);和
  • 当两个名称都表示函数时,函数(11.3.5)的参数类型列表相同;和
  • 当两个名称都表示函数模板时,签名(17.5.6.1)相同。

有人可能会说,由于X::M::g也是通过 using-declaration 带入X的,因此它也是X的成员。意味着在它和另一个X::g之间满足所有4个标准。(文本并没有明确说明 using-declaration 是否声明某个东西是它出现的名称空间的成员。因此,我认为这个问题当时并没有完全解决。
然而,在C++23草案中,它确实得到了解决。参见N4928 [basic.scope.scope]/2.4,[basic.scope.scope]/5,[basic.link]/8,[namespace.udecl]/10。

相关问题