由于历史原因,我有一个位于顶级命名空间中的类。我需要为它定义一个必须使用参数相关查找找到1的函数。顶级名称空间是否被视为此类的关联名称空间,还是我必须采取一些解决方法?
1否则使用它的模板可能找不到它,因为在模板之后定义的符号只有在 ADL 找到时才能看到。
由于历史原因,我有一个位于顶级命名空间中的类。我需要为它定义一个必须使用参数相关查找找到1的函数。顶级名称空间是否被视为此类的关联名称空间,还是我必须采取一些解决方法?
1否则使用它的模板可能找不到它,因为在模板之后定义的符号只有在 ADL 找到时才能看到。
全局命名空间在这方面并不特殊,它就像任何其他命名空间一样工作,因此非常适合您的用例。
ADL 的实时示例 2实际上是 #1 起作用的原因1。
这是现场示例的文本:
#include <iostream>
struct X {};
template <class T>
void bar(T t)
{
foo(t);
}
void foo(X x)
{
std::cout << "Foo\n";
}
int main()
{
X x;
bar(x);
}
1这失败了,因为 ADL 找不到函数,而正常查找会。因此,它证明了#1 确实有效,这要归功于 ADL。
这是我对标准的看法:
来自 [basic.lookup.argdep] (2):
— 如果 T 是类类型(包括联合),则其关联的类是:类本身;它所属的类别(如有的话);及其直接和间接基类。其关联的命名空间是其关联类的最内层封闭的命名空间。
从 [basic.namespace] (2) (和 3.3.6global namespace
定义的地方):
翻译单元的最外层声明区域是命名空间;见 3.3.6。
所以我看不到任何东西可以从 ADL 中排除全局命名空间。