c++ - 对 C++ 中的命名空间和参数相关查找感到困惑

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

我一直在阅读 Bjarne Stroustrup 所著的《C++ 编程语言》中的命名空间章节,并对如何使用参数依赖查找来调用函数感到困惑。以下是书中的代码片段:

代码片段 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 确实接着说“如果参数是命名空间的成员,则关联的命名空间就是封闭的命名空间。”由于 g 的参数是命名空间 N 的成员,这是否意味着封闭的命名空间是不包含函数“h(int)”的全局命名空间?如果是这样的话,如果封闭的命名空间是也不包含“format(Date)”函数的全局命名空间,为什么 Snippet 1 不会失败?

预先感谢您对此事的深入了解!

最佳答案

ADL 应用基于调用本身的参数类型,而不是调用可能位于或不位于的函数的参数类型。

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

关于c++ - 对 C++ 中的命名空间和参数相关查找感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37151092/

相关文章:

javascript - 如何在严格模式下找到匿名函数的元数?

c++ - 函数模板的部分排序和非推导上下文在 MSVC 2017 中不起作用

c++ - qt c++ new 类似的方法。我是重载方法、编写新方法还是使用默认参数?

C++编程帮助!它不会工作?

function - 如何使用 vue.js 在 @click 事件上添加两个方法?

java - 在 Java 中停止计时器事件

javascript - 在对象构造函数中使用 'this' 变量

javascript - 无法访问回调函数 React 中的属性

c++ - 在 std::vector 中查找迭代器

c++ - 在执行代码之前进入函数时引发异常