bry*_*mon 3 c++ argument-dependent-lookup
我一直在阅读Josuttis模板书,我一直试图把我的脑袋放在ADL周围.他说"ADL通过查找名称空间和类中的名称"与"调用参数的类型"相关联.我只是想看看它是如何工作的,在课堂上查找名字.我在下面举了一个测试例子.我看到它如何在命名空间中查找名称.
class bryan_ns {
public:
class bryan {
public:
enum E { e1 };
static void bryan_test() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
void f(bryan::E) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
void f(int)
{
std::cout << "::f(int) called\n";
}
int main()
{
f(bryan_ns::bryan::e1); // calls ::f(int)
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将bryan_ns更改为如此命名空间:
namespace bryan_ns {
public:
class bryan {
public:
enum E { e1 };
static void bryan_test() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
void f(bryan::E) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
void f(int)
{
std::cout << "::f(int) called\n";
}
int main()
{
f(bryan_ns::bryan::e1); // calls bryan_ns::f(bryan::E)
}
Run Code Online (Sandbox Code Playgroud)
ADL将查看该类型的封闭命名空间,以及类型本身内部.最好的例子是在类型中定义的友元函数:
namespace X {
class test {
friend void f( test ) { std::cout << "test" << std::endl; }
};
}
int main() {
X::test t;
f( t );
}
Run Code Online (Sandbox Code Playgroud)
调用f(t)将发现X::f其声明仅在类型内可用test.这是友元函数声明的一个鲜为人知的特性:它们声明了命名空间级别函数,但仅在类型内部提供声明.验证此行为的简单测试:
namespace X {
class test {
friend void f( test );
};
//void f( test ); // [1]
}
void X::f( X::test ) {} // [2]
int main() {
X::test t;
f(t); // [3]
}
Run Code Online (Sandbox Code Playgroud)
[2]中的定义将触发编译错误,因为您只能定义已声明的函数,并且[2]在命名空间之外,该X定义不用于自我声明的目的(如果您定义在它所驻留的命名空间内的函数,那么该定义也是一个声明,但在这种情况下不是).如果我们取消注释[1],错误就会消失.或者,如果我们注释[2],代码将编译,表明对于[3]中的调用,ADL已在类中找到了声明.
| 归档时间: |
|
| 查看次数: |
751 次 |
| 最近记录: |