C++ 依赖于参数的查找——何时完成,搜索什么,如何强制(或阻止)它?

C++ 依赖于参数的查找——何时完成,搜索什么,如何强制(或阻止)它?,c++,argument-dependent-lookup,C++,Argument Dependent Lookup,我很难理解参数相关(Koenig)查找背后的规则 考虑以下代码: #include <iostream> using namespace std; namespace adl { struct Test { }; void foo1(Test const &) { cout << "ADL used (foo1)" << endl; } void foo2(Test const &) { cout <<

我很难理解参数相关(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));
}
#包括
使用名称空间std;
名称空间adl
{
结构测试{};

void foo1(Test const&){cout您的问题并不是依赖于参数的查找。首先,依赖于参数的查找只可能在对函数进行非限定查找时出现。当调用
foo1(t)
foo1
时,foo1是一个类型,它的模板构造函数被调用。类似地,
foo3(t)
是一个合格的查找,因为
foo3
是一个对象,函数调用运算符在对象的类
foo1
中查找。参数查找进入图片的唯一位置是调用
foo2(t)
,其中查找查找到候选项:

  • ::foo2(adl::Test const&)
  • ::adl::foo2(adl::Test const&)
  • 这两个函数被交给重载解析,因为这两个函数都是同样好的匹配,所以非模板函数获胜

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

  • 查名字的血淋淋的细节太广泛了,因此,这个问题是要求写一篇文章,我忽略了
  • 你的第二个问题扩展到另外三个问题,只有一个似乎相关:
  • 搜索哪些范围?在函数定义中查找非限定函数名时,规则取决于是否有任何名称是从属名称。如果没有此类名称(即,在非模板代码中或在模板代码中,可以在第一阶段确定名称),则在封闭的名称空间和与其参数关联的名称空间中查找名称。否则,仅在关联的名称空间中查找名称
  • 是否可以强制进行参数相关的查找?如果存在至少一个参数,则始终会对非限定函数进行查找,但找到的名称可能更匹配。当然,您需要调用非限定函数,否则将无法进行查找

  • -1这个问题太宽泛了,代码示例真的很烂(有误导性的名称等等)。我不明白。你为什么要试验
    (foo3(t));
    ?没有名为
    foo3
    )的函数。因此ADL不会出现。毫无疑问,
    foo3
    将被视为对象,因为这就是它(这意味着它将毫无疑问地调用
    操作符()
    )!这只是您在示例中使用的误导性名称。@Nawaz:显然,我没有粘贴代码的这一部分,非常感谢您指出它,它将修复它。(输出确实是,当包含foo3时,不使用ADL。)@迈尔达德:不客气。希望你学到了一些东西。下次请努力回答你的问题。@Cheers-sandhth。-阿尔夫:你的粗鲁都是因为我错过了粘贴
    foo3
    ?我希望我不是唯一一个找到你的“Cheers-and-hth”的人具有讽刺意味的是,到目前为止,你所说的一切都没有任何建设性的意义。如果你对如何改进这个问题有想法,那么我洗耳恭听,但真的没有必要称我为白痴……仍然试图理解是什么让调用“不合格”。我认为“不合格”意味着“没有提到限定符(即名称空间)”…但显然情况并非如此,因为所有这些都没有提到名称空间?调用不合格意味着什么?当查找名称时,它首先引用名称,并在找到名称时停止。
    foo1
    查找类型并在类型上下文中查找要调用的构造函数。因为类型是在f之前找到的函数,不考虑其他名称空间。类似地,对于
    foo3
    ,在对象类型的cintext中查找函数调用运算符的对象。对于
    foo2
    ,找到函数且调用不合格,即搜索与参数关联的名称空间以增加重载这是对编译器遵循的过程的一个很好的描述,但我仍然不理解“限定”是什么意思。您似乎将限定定义为“导致ADL的任何调用”,然后说ADL只适用于不合格的呼叫…这在定义上是正确的,但并不能帮助我理解什么是合格的呼叫。但什么使呼叫合格,确切地说?我如何判断给定的呼叫是否合格?不,我想我不知道:不合格是指没有提供上下文。合格是指有上下文时提供的上下文可以是名称空间、类型或对象(可能还有其他的,但我想不出任何)。@DietmarKühl:你说的“上下文”或“无上下文”是什么意思?在这段代码中:
    模板void f(t t){std::sort;sort(t.begin(),t.end());}
    这里是限定的还是非限定的?