6

我无法理解参数相关(Koenig)查找背后的规则。

考虑下面的代码:

#include <iostream>

using namespace std;

namespace adl
{
    struct Test { };
    void foo1(Test const &) { cout << "ADL used (foo1)" << endl; }
    void foo2(Test const &) { cout << "ADL used (foo2)" << endl; }
    void foo3(Test const &) { cout << "ADL used (foo3)" << endl; }
}

struct foo1
{
    foo1() { }

    template<class T>
    foo1(T const &) { cout << "ADL not used (foo1)" << endl; }

    template<class T>
    void operator()(T const &) const { cout << "ADL not used (foo3)" << endl; }
};

template<class T> void foo2(T const &)
{ cout << "ADL not used (foo2)" << endl; }

int main()
{
    adl::Test t;
    foo1 foo3;
    (foo1(t));
    (foo2(t));
    (foo3(t));
}

它的输出是:

未使用ADL ( foo1)
已使用 ADL ( foo2)
未使用 ADL ( foo3)

我希望他们所有人都使用 ADL,但令我惊讶的是只有其中一些人使用了 ADL。

ADL 规则背后的(可能是血淋淋的,我知道)细节是什么?
我很好地理解了这个概念,但细节是我遇到的麻烦。

搜索哪些范围,何时搜索,何时不搜索?

是否完全有可能判断是否使用了 ADL 而无需在给定的代码行之前查看所有'#include d 文件?我希望函子和函数在 [not] 屏蔽 ADL 方面表现相同,但显然它们没有。

如果ADL 不是自动完成(例如上面的)并且您不知道类的命名空间(例如在模板中),有什么方法可以强制ADL?

4

1 回答 1

5

您的问题实际上与参数相关查找无关。首先,依赖于参数的查找只有在对函数进行非限定查找时才有可能进入画面。当调用foo1(t) foo1是一个类型并且它的模板化构造函数被调用。同样,foo3(t)is 是一个合格的查找,因为foo3is 是一个对象,并且函数调用运算符是在对象的 class 中查找的foo1。参数查找进入图片的唯一地方是调用foo2(t)查找查找候选人的地方:

  1. ::foo2<adl::Test>(adl::Test const&)
  2. ::adl::foo2(adl::Test const&)

这两个函数被移交给重载决议,因为这两个函数都很好地匹配非模板函数获胜。

你的问题实际上是三个问题:

  1. 名字查询的血淋淋的细节太宽泛了,因此,这个问题是要求写一篇我忽略的文章。
  2. 您的第二个问题扩展到另外三个问题,只有一个似乎相关:
    1. 搜索哪些范围?在函数定义中查找非限定函数名称时,规则取决于是否有任何名称是从属名称。如果没有这样的名称(即,在非模板代码中或在可以在第一阶段确定名称的模板代码中),则在封闭的名称空间和与其参数关联的名称空间中查找名称。否则,仅在关联的命名空间中查找名称。
  3. 可以强制依赖参数查找吗?如果至少有一个参数但找到的名称可能更好匹配,则始终对不合格的函数查找进行此操作。当然,你需要调用一个不合格的函数,否则它不会完成。
于 2013-01-05T11:41:24.953 回答