微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

依赖限定名的查找 [temp.res.general]/6.1

如何解决依赖限定名的查找 [temp.res.general]/6.1

此程序无法编译 (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(); 的声明,它会编译。 Demo

两个版本都有错误foo 即使声明,也不接受任何参数。下面的问题是自己提出来的。

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

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

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

其实第一步不用实例化就可以完成。编译器似乎这样做了,如果没有找到 foo,它会诊断错误(这是可选的)。如果至少找到一个 foo,则无需进一步分析。

解决方法

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

您正在寻找的标准部分是:

[temp.res.general]/6.1

程序格式错误,无需诊断,如果:

——不能为模板生成有效的特化...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。