有3个例子:
我
typedef int foo;
namespace B
{
struct S
{
operator int(){ return 24; }
};
int foo(B::S s){ return 0; }
}
int main()
{
int t=foo(B::S()); //24, ADL does not apply
}
II。
namespace B
{
struct S
{
operator int(){ return 24; }
};
int foo(B::S s){ return 0; }
}
int main()
{
int t=foo(B::S()); //0, ADL applies
}
III。
namespace B
{
struct S
{
operator int(){ return 24; }
};
int foo(B::S s){ return 0; }
}
int foo(B::S s){ return 12; }
int main()
{
int t=foo(B::S()); //error: call of overloaded ‘foo(B::S)’ is ambiguous
//ADL applies
}
我不清楚ADL查找的实际条件是什么?我需要参考标准描述它。
答案 0 :(得分:2)
这个标准段落澄清了,甚至有一个例子非常像你的第一个例子。
3.4.1 / 3:
3.4.2 [basic.lookup.argdep]中描述了用作函数调用的 postfix-expression 的非限定名称的查找。 [注意:为了确定(在解析期间)表达式是否为函数调用的 postfix-expression ,通常的名称查找规则适用。 3.4.2中的规则对表达式的句法解释没有影响。例如,
typedef int f;
namespace N {
struct A {
friend void f(A &);
operator int();
void g(A a) {
int i = f(a); // f is the typedef, not the friend
// function: equivalent to int(a)
}
};
}
因为表达式不是函数调用,所以依赖于参数的名称查找(3.4.2)不适用,并且找不到友元函数
f
。 - 结束记录]
答案 1 :(得分:1)
您的第一个示例并未说明ADL。在行
int t=foo(B::S());
foo
typedef
为int
。
以下代码有一些更好的ADL插图。
#include <iostream>
namespace B
{
struct S
{
operator int(){ return 24; }
};
int foo(S s){ return 100; }
int bar(S s){ return 400; }
}
namespace C
{
struct S
{
operator int(){ return 24; }
};
int foo(S s){ return 200; }
}
int bar(C::S s){ return 800; }
int main()
{
// ADL makes it possible for foo to be resolved to B::foo
std::cout << foo(B::S()) << std::endl;
// ADL makes it possible for foo to be resolved to C::foo
std::cout << foo(C::S()) << std::endl;
// ADL makes it possible for bar to be resolved to B::bar
std::cout << bar(B::S()) << std::endl;
// ADL makes it possible for bar to be resolved to ::bar
std::cout << bar(C::S()) << std::endl;
}