我一直在阅读Bjarne Stroustrup的C ++编程语言中的命名空间章节,并对如何使用Argument-Dependent Lookup调用函数感到困惑。以下是本书的代码片段:
Snippet 1
namespace Chrono {
class Date { /* ... */ };
bool operator==(const Date&, const std::string&);
std::string format(const Date&); // make string representation
// ...
}
void f(Chrono::Date d, int i)
{
std::string s = format(d); // Chrono::format()
std::string t = format(i); // error: no format() in scope
}
这段代码对我有意义,因为Chrono是函数f参数中使用的命名空间,因此可以成功搜索格式(Date)函数。它似乎函数f和命名空间Chrono共享相同的范围,这使我对下一个片段感到困惑:
Snippet 2
namespace N {
struct S { int i };
void f(S);
void g(S);
void h(int);
}
struct Base {
void f(N::S);
};
struct D : Base {
void mf();
void g(N::S x)
{
f(x); // call Base::f()
mf(x); // call D::mf()
h(1); // error: no h(int) available
}
};
这对我来说很有意义,直到第一行" h(1);"由于结构和名称空间N都具有相同的范围,为什么不能使用函数" void h(int)"在命名空间N?
中找到Stroustrup继续说"如果参数是命名空间的成员,则关联的命名空间是封闭的命名空间。"由于g的参数是命名空间N的成员,这是否意味着封闭命名空间是不包含函数的全局命名空间" h(int)"?如果是这种情况,如果封闭命名空间是全局命名空间,也不会包含"格式(日期)"功能
提前感谢您对此事的深入了解!
答案 0 :(得分:2)
ADL根据调用本身中的参数类型应用,而不是调用可能或可能不在的函数的参数类型。
在format(d)
中,在format
中查找Chrono
,因为该调用的参数d
属于Chrono::Date
类型,Chrono
1}}是该类型的关联命名空间。包含呼叫的功能是void f(Chrono::Date d, int i)
还是void f()
无关紧要。 (显然,在后一种情况下,假设有一个Chrono::Date d;
。)