c++ - 普通查找和隐藏

标签 c++ language-lawyer name-lookup

<分区>

以下程序编译( live demo ),但我不明白为什么。

namespace N {
    struct S {};
}


void Foo(N::S);


namespace Lib {
    template <class T>
    void Call() { Foo(T{}); }

    void Foo();
}


int main()
{
    Lib::Call<N::S>();
}

不应该Lib::Foo隐藏::FooFooCall是一个依赖名称,依赖名称的评估应该推迟到模板的实例化。在这种情况下名称查找如何工作?

在命名空间 Lib Foo(N::S{})可以在声明void Foo();之前调用, 但不能在声明后调用,因为 Lib::Foo隐藏 ::Foo . Lib::Call<N::S>();在声明之后,所以绑定(bind)名称时 Foo到这里,隐藏应该生效了吧?

最佳答案

在模板中使用的名称的所有非 ADL 查找都来自模板定义,即使在 ADL 可能提供从实例化上下文中找到的声明的情况下,在实例化之前使用结果也是如此。

您可以从“空间”的意义上考虑这一点——依赖查找的两个部分同时从不同的地方发生(限制它们找到的内容)——或者从“时间”的意义上——非依赖的—— ADL 查找在解析模板时发生,结果被保存并在实例化期间与依赖的 ADL 结果合并。前者是标准描述它的方式(以避免将编译描述为依赖时间的过程),但后者直观地解释了出于解析目的对依赖名称的处理(因此当 typename模板是必需的)。

针对不同类型的名称(C++20 中的 [temp.res]/1.3[temp.nondep]/1[temp.dep.candidate]/1),此标准规则分散在多个案例中。

关于c++ - 普通查找和隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63185185/

相关文章:

c - 删除功能是否保证删除文件?

具有通用版本 8 和 17 的 Java 实例类型

c++ - OpenSSL : Encrypt a symmetric key with an ECC public key

c++ - 为什么模板只能在头文件中实现?

c - C 中除以零和未定义的行为

c++ - 有关使用好友功能查找姓名的问题

c++ - ISO C++ 草案 - 3.4.2/3 - 参数相关名称查找

c++ - 这个模板解析冲突叫什么?

c++ - 定义新的中缀运算符

c++ - 使用序列优雅地初始化静态(成员)数组