繁体   English   中英

为什么using指令不会影响ADL?

[英]Why doesn't a using directive affect ADL?

我试图理解为什么以下代码无法编译:

namespace ns {
  struct S {};
}

namespace alleq {
  inline bool
  operator==(const ns::S &, const ns::S &)
  {
    return true;
  }
}

namespace ns {
  using namespace alleq;
  // using alleq::operator==; // Works if you uncomment this
}

ns::S a;

void
f()
{
  ::ns::operator==(a, a); // OK
  a == a;                 // Error: no match for 'operator=='
}

函数f的第一行确实编译,这让我相信命名空间ns包含一个函数operator== 但是,当我比较两个类型为ns::S值时,找不到此operator==函数。 相比之下,using声明确实按预期工作,并允许f的第二行通过ADL查找ns::operator==

我怀疑其原因在于,使用using 指令会使符号看起来像是在全局名称空间:: :(因为这是命名空间alleqns的共同祖先)。 但如果确实如此,那么为什么::ns::operator==找到函数呢?

更一般地说,我试图在库中提供一些有用的operator== (和相关的)重载,但是如果他们不想要它们,则不强迫人们使用这些定义。 我希望允许人们根据他们是否将专用运算符命名空间导入到他们自己的命名空间中来启用或不启用operator ==(以及相关的其他运算符)。 现在看起来人们可能不得不编写一些使用声明的东西 (我可以用宏来简化,但是很糟糕)。

我怀疑其原因在于,使用using 指令会使符号看起来像是在全局名称空间:: :(因为这是命名空间alleqns的共同祖先)。

这有点真实,但仅适用于不合格的查找,而不是依赖于参数的查找:

7.3.4 [namespace.udir]:

  1. using-directive指定指定命名空间中的名称可以在using-directive出现在using-directive之后的范围内使用 在非限定名称查找(3.4.1)期间,名称看起来好像是在最近的封闭命名空间中声明的,其中包含using-directive和指定的命名空间。

由于这仅适用于非限定名称查找,因此当名称查找“向外”进入封闭名称空间时,它仅在从封闭名称空间内执行名称查找时才有用。 它无法帮助从命名空间外部找到不合格的名称(这是ADL所做的)。

下一段说明:

  1. using-directive不会将任何成员添加到它出现的声明区域。

即using指令使作用域中的名称可见,但不向作用域添加新的声明。

你看到的行为的原因很简单,标准说ADL忽略使用指令:

3.4.2 [basic.lookup.argdep]

  1. 在考虑关联的命名空间时,查找与关联命名空间用作限定符时执行的查找相同(3.4.3.2),但以下情况除外:
    - 忽略关联命名空间中的任何using-directive。

暂无
暂无

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

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