对C ++中的命名空间和Argument-Dependent Lookup感到困惑

时间:2016-05-11 00:25:37

标签: c++ function scope namespaces argument-dependent-lookup

我一直在阅读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)"?如果是这种情况,如果封闭命名空间是全局命名空间,也不会包含"格式(日期)"功能

提前感谢您对此事的深入了解!

1 个答案:

答案 0 :(得分:2)

ADL根据调用本身中的参数类型应用,而不是调用可能或可能不在的函数的参数类型。

format(d)中,在format中查找Chrono,因为该调用的参数d属于Chrono::Date类型,Chrono 1}}是该类型的关联命名空间。包含呼叫的功能是void f(Chrono::Date d, int i)还是void f()无关紧要。 (显然,在后一种情况下,假设有一个Chrono::Date d;。)