C++ 相关限定名的查找
此程序未编译(C++ 相关限定名的查找,c++,name-lookup,dependent-name,qualified-name,C++,Name Lookup,Dependent Name,Qualified Name,此程序未编译(错误:“foo”不是“N”的成员): 名称空间N{ //void foo(); } 模板 无效模板函数(T){ N::foo(t); } 但是如果我们取消注释void foo()的声明,它编译 两个版本都有一个错误foo即使声明,也不接受任何参数。提出了以下问题 为什么一个版本可以编译,而另一个版本不能编译 《C++标准》中有一条规则,它是这样的吗?如果编译器能够证明任何实例化的格式都不正确,那么它可以(但不是必须)在不实例化的情况下诊断错误 我的理论如下(正确吗?)。在te
错误:“foo”不是“N”的成员
):
名称空间N{
//void foo();
}
模板
无效模板函数(T){
N::foo(t);
}
但是如果我们取消注释void foo()的声明代码>,它编译
两个版本都有一个错误foo
即使声明,也不接受任何参数。提出了以下问题
- 为什么一个版本可以编译,而另一个版本不能编译
《C++标准》中有一条规则,它是这样的吗?如果编译器能够证明任何实例化的格式都不正确,那么它可以(但不是必须)在不实例化的情况下诊断错误
我的理论如下(正确吗?)。在template_func
N::foo
中,同时是限定名和从属名。依赖名称的查找将推迟到模板的实例化。查找名称(如果成功)将导致将名称的使用与该名称的声明绑定。但是这个过程由两个步骤组成(现在只考虑有资格的名称,看起来像函数调用):
在限定符的作用域中查找名称(在本例中,这意味着名称空间N
)。这可能会找到多个名称,因为函数可以重载
检查参数是否可以传递给找到的名称。这包括在N
中有多个foo
时查找最佳匹配。通过这种方式,N::foo
的使用与N::foo
声明相关联
实际上,第一步不需要实例化就可以完成。编译器似乎会这样做,如果没有找到foo
,它会诊断错误(这是可选的)。如果至少发现一个foo
,则无需进一步分析。您的分析似乎是正确的,并且您的代码格式不正确,无需诊断,无论void foo()代码>是否被注释掉
您正在寻找的标准部分是:
如果出现以下情况,程序格式不正确,无需诊断:
-无法为模板生成有效的专门化
namespace N {
// void foo();
}
template<class T>
void template_func(T t) {
N::foo(t);
}