提问人:Dr. Gut 提问时间:3/21/2021 最后编辑:Dr. Gut 更新时间:9/28/2023 访问量:50
从属限定名称的查找
Lookup of dependent qualified names
问:
此程序不编译 ():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_func
N::foo
- 在限定符的作用域中查找名称(在本例中,这意味着 namespace )。这可能会找到多个名称,因为函数可能会重载。
N
- 检查参数是否可以传递给找到的名称。这包括查找最佳匹配项(如果 中有多个匹配项)。这样,将 的用法与声明相关联。
foo
N
N::foo
N::foo
实际上,第一步可以在没有实例化的情况下完成。编译器似乎这样做了,如果没有找到,它会诊断错误(这是可选的)。如果至少找到一个,它不会费心进行进一步的分析。foo
foo
答:
2赞
HolyBlackCat
3/21/2021
#1
您的分析似乎是正确的,并且您的代码格式不正确,无论是否被注释掉,都不需要诊断。void foo();
您要查找的标准部分是:
[temp.res.general]/6.1
如果出现以下情况,程序格式不正确,无需诊断:
— 无法为模板生成有效的专用化...
评论