lyt*_*nyn 22 c++ namespaces argument-dependent-lookup
我在这里有一小段代码供您考虑,这让我感到非常困惑.奇怪的是,它在Sun Studio和GCC上编译,即使我认为它不应该.
考虑一下:
namespace name
{
class C
{
int a;
};
void f(C c);
void g(int a);
}
int main(int argc, char** argv)
{
name::C c;
name::f(c);
f(c); // <--- this compiles, strangely enough
name::g(42);
// g(42); <--- this does not, as I expected
}
Run Code Online (Sandbox Code Playgroud)
来自同一命名空间的类参数会导致函数f"泄漏"到命名空间之外,并且无需访问name::.
有人对此有解释吗?这当然是我而不是编译器在这里错了.
Nik*_*sov 12
这是Argument-Dependent Name Lookup,又名ADL,又名Koenig查找.这是为了使运营商按预期工作而发明的,例如:
namespace fu {
struct bar { int i; };
inline std::ostream& operator<<( std::ostream& o, const bar& b ) {
return o << "fu::bar " << b.i;
}
}
fu::bar b;
b.i = 42;
std::cout << b << std::endl; // works via ADL magic
Run Code Online (Sandbox Code Playgroud)
如果没有ADL,你必须明确地使输出操作符变得丑陋using fu::operator<<;,或者使用更加丑陋的显式调用:
fu::operator<<( std::cout, b ) << std::endl;
Run Code Online (Sandbox Code Playgroud)
这是由于"参数依赖查找".删除const不会改变您所看到的行为.要证明它是ADL,请尝试将St结构移动到命名空间之外...
struct St
{
int a;
};
namespace name
{
void f(const St& st);
void g(int a);
}
int main(int argc, char** argv)
{
St st;
name::f(st);
f(st); // <--- now you will get the expected compile error
name::g(42);
// g(42); <--- this does not, as I expected
}
Run Code Online (Sandbox Code Playgroud)