从属限定名称的查找

Lookup of dependent qualified names

提问人:Dr. Gut 提问时间:3/21/2021 最后编辑:Dr. Gut 更新时间:9/28/2023 访问量:50

问:

此程序不编译 ():error: 'foo' is not a member of 'N'

namespace N {
//    void foo();
}

template<class T>
void template_func(T t) {
    N::foo(t);
}

但是,如果我们取消注释 的声明,它就会编译。演示void foo();

两个版本都有错误。 即使声明,也不带任何参数。以下问题自告奋勇。foo

  • 为什么一个版本可以编译,而另一个版本不能编译?
  • C++ 标准中是否有这样的规则?“如果编译器能够证明没有实例化可以很好地格式化,那么它可能(但不是必需的)在没有实例化的情况下诊断错误。

我的理论如下(正确吗?里面同时是一个限定名称和一个从属名称。依赖项名称的查找将推迟到模板实例化之前。查找名称(如果成功)会导致将名称的用法与该名称的声明相关联。但此过程包括两个步骤(现在让我们只考虑限定名称,看起来像函数调用):template_funcN::foo

  1. 在限定符的作用域中查找名称(在本例中,这意味着 namespace )。这可能会找到多个名称,因为函数可能会重载。N
  2. 检查参数是否可以传递给找到的名称。这包括查找最佳匹配项(如果 中有多个匹配项)。这样,将 的用法与声明相关联。fooNN::fooN::foo

实际上,第一步可以在没有实例化的情况下完成。编译器似乎这样做了,如果没有找到,它会诊断错误(这是可选的)。如果至少找到一个,它不会费心进行进一步的分析。foofoo

C++ 查找 依赖项 限定名称

评论


答:

2赞 HolyBlackCat 3/21/2021 #1

您的分析似乎是正确的,并且您的代码格式不正确,无论是否被注释掉,都不需要诊断。void foo();

您要查找的标准部分是:

[temp.res.general]/6.1

如果出现以下情况,程序格式不正确,无需诊断:

— 无法为模板生成有效的专用化...