对 C++ 中的名称空间和参数相关查找感到困惑
Confused about namespaces and Argument-Dependent Lookup in C++
我一直在通读 Bjarne Stroustrup 撰写的 The C++ Programming Language 中的名称空间章节,并对如何使用参数相关查找调用函数感到困惑。以下是书中的代码片段:
片段 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 的参数中使用的命名空间,因此可以成功地搜索 format(Date) 函数。它还显示函数 f 和命名空间 Chrono 共享相同的范围,这让我对下一个片段感到困惑:
片段 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 共享相同的范围,为什么不能在命名空间 N 中找到函数 "void h(int)"?
Stroustrup 继续说 "If an argument is a member of a namespace, the associated namespaces are the enclosing namespaces." 因为 g 的参数是命名空间 N 的成员,这是否意味着封闭的命名空间是不包含函数的全局命名空间 "h(int)" ?如果是这样的话,如果封闭的命名空间是也不包含 "format(Date)" 函数的全局命名空间,为什么代码段 1 不会失败?
在此先感谢您对此事的深入了解!
ADL 的应用基于调用本身的参数类型,而不是调用可能在也可能不在的函数的参数类型。
在 format(d)
中,format
在 Chrono
中查找,因为该调用的参数 d
属于 Chrono::Date
类型,并且Chrono
是该类型的关联命名空间。包含调用的函数是 void f(Chrono::Date d, int i)
还是 void f()
无关紧要。 (显然,在后一种情况下,假设有一个 Chrono::Date d;
。)
我一直在通读 Bjarne Stroustrup 撰写的 The C++ Programming Language 中的名称空间章节,并对如何使用参数相关查找调用函数感到困惑。以下是书中的代码片段:
片段 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 的参数中使用的命名空间,因此可以成功地搜索 format(Date) 函数。它还显示函数 f 和命名空间 Chrono 共享相同的范围,这让我对下一个片段感到困惑:
片段 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 共享相同的范围,为什么不能在命名空间 N 中找到函数 "void h(int)"?
Stroustrup 继续说 "If an argument is a member of a namespace, the associated namespaces are the enclosing namespaces." 因为 g 的参数是命名空间 N 的成员,这是否意味着封闭的命名空间是不包含函数的全局命名空间 "h(int)" ?如果是这样的话,如果封闭的命名空间是也不包含 "format(Date)" 函数的全局命名空间,为什么代码段 1 不会失败?
在此先感谢您对此事的深入了解!
ADL 的应用基于调用本身的参数类型,而不是调用可能在也可能不在的函数的参数类型。
在 format(d)
中,format
在 Chrono
中查找,因为该调用的参数 d
属于 Chrono::Date
类型,并且Chrono
是该类型的关联命名空间。包含调用的函数是 void f(Chrono::Date d, int i)
还是 void f()
无关紧要。 (显然,在后一种情况下,假设有一个 Chrono::Date d;
。)