C++ 无模板ADL
你能给我举一个不使用模板的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
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);
}