C++ 无模板ADL

C++ 无模板ADL,c++,templates,argument-dependent-lookup,C++,Templates,Argument Dependent Lookup,你能给我举一个不使用模板的ADL的例子吗?从没见过这样的事。我的意思是类似于。具体来说,我感兴趣的例子中,它导致了一些陷阱,如所提到的 编辑: 我认为托马拉克的回答可以延伸到陷阱。考虑这一点: namespace dupa { class A { }; class B : public A { public: int c; B() { } }; void f(B b) { print

你能给我举一个不使用模板的ADL的例子吗?从没见过这样的事。我的意思是类似于。具体来说,我感兴趣的例子中,它导致了一些陷阱,如所提到的

编辑:

我认为托马拉克的回答可以延伸到陷阱。考虑这一点:

namespace dupa {

    class A {
    };

    class B : public A {
    public:
        int c;
        B() {
        }
    };

   void f(B b) {
       printf("f from dupa called\n");
   }
}

void f(dupa::A) {
    printf("f from unnamed namespace called\n");
}


int main()
{   
    dupa::B b;
    f(b);

    return 0;
}

在这里,我们希望调用未命名名称空间中的f,但会调用另一个。

我不能向您展示导致陷阱的东西,但我可以演示:


注意lol的类型必须是类类型;正如您所看到的,我最初尝试使用内置软件,但没有成功。

我无法向您展示导致陷阱的东西,但我可以演示:


注意lol的类型必须是类类型;正如您所看到的,我最初尝试使用内置函数,但它不起作用。

造成混淆的诀窍是创建一个场景,其中函数的参数是可互换的或可转换的,ADL可能会选择一些可能不是您所期望的。我不确定这是否令人印象深刻或只是预期:


类型相同,但ADL将检查参数的静态类型,并将该名称空间添加到搜索中。这反过来意味着,确切的静态类型可能使不同的函数对编译器可见。当ADL或重载解析可以应用于多个参数时,事情可能会更加混乱。

造成混乱的诀窍是创建一个场景,其中函数的参数可以互换或转换,并且ADL可能会选择一些可能不是您所期望的。我不确定这是否令人印象深刻或只是预期:

类型相同,但ADL将检查参数的静态类型,并将该名称空间添加到搜索中。这反过来意味着,确切的静态类型可能使不同的函数对编译器可见。当ADL或重载解析可以应用于多个参数时,事情可能会更加混乱。

没有模板。 使用交换,因为这是最常见的用法

#include <iostream>

namespace One
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-One A\n";}
}

namespace Two
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-Two A\n";}
}


int main()
{
    One::A      oneA_l;
    One::A      oneA_r;
    Two::A      twoA_l;
    Two::A      twoA_r;

    swap(oneA_l, oneA_r);
    swap(twoA_l, twoA_r);
}
没有模板。 使用交换,因为这是最常见的用法

#include <iostream>

namespace One
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-One A\n";}
}

namespace Two
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-Two A\n";}
}


int main()
{
    One::A      oneA_l;
    One::A      oneA_r;
    Two::A      twoA_l;
    Two::A      twoA_r;

    swap(oneA_l, oneA_r);
    swap(twoA_l, twoA_r);
}

是的,还有?@Tomalak,因为lol的类型是int。我建议您更改名称空间名称,可能会有人对此感到不快。@Tomek:dupa在波兰语中相当于英语foo-如果几乎所有人都使用它,谁会因此而不快-是的,还有?@Tomalak,因为lol的类型是int。我建议您更改名称空间名称,可能会有人对此感到不快。@Tomek:dupa在波兰语中相当于英语foo-如果几乎所有人都使用它,谁会因此而不快-请注意,其效果与使用非虚拟方法完全相同:静态类型确定在重载中使用哪些方法,这是通过设计实现的:ADL使用的语言使得自由函数可以像成员函数一样作为类型的扩展。请注意,其效果与使用非虚拟方法完全相同:静态类型决定在重载中使用哪些方法,这是通过设计实现的:ADL采用了这种语言,因此自由函数可以像成员函数一样作为类型的扩展。
#include <iostream>

namespace One
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-One A\n";}
}

namespace Two
{
    class A {};
    void swap(A& lhs, A& rhs) { std::cout << "Swap-Two A\n";}
}


int main()
{
    One::A      oneA_l;
    One::A      oneA_r;
    Two::A      twoA_l;
    Two::A      twoA_r;

    swap(oneA_l, oneA_r);
    swap(twoA_l, twoA_r);
}