【问题标题】:A confusion about function name lookup关于函数名查找的困惑
【发布时间】:2020-08-06 07:53:13
【问题描述】:

我对标准中的一些规则感到困惑。我会在这里引用它们:

[basic.lookup.argdep]:

令 X 为 非限定查找 生成的查找集,让 Y 为参数相关查找(定义如下)生成的查找集。

所以上面这句话的意思是集合X是由unqualified lookup创建的。然后我们看看非限定查找的规则:

[basic.lookup.unqual]:

在 [basic.lookup.unqual] 中列出的所有情况下,将按照每个相应类别中列出的顺序搜索范围以查找声明; 一旦找到名称的声明,名称查找就会结束

强调的部分“一旦找到名称的声明,名称查找就结束”表示一旦找到名称,查找就停止。

所以我的问题是:

void func(int){}
void func(double){}
int main(){
  func(0);
}

考虑上面的代码。 fun 的名称以非限定方式使用。因此执行不合格的查找规则。因此,一旦找到func(double)func(int),就会停止查找。那么,为什么func 可以重载,即候选函数集同时包含func(int)func(double)?它不与不合格的查找规则相矛盾吗?如果我遗漏了什么,请纠正我。

【问题讨论】:

  • 0 是一个整数值。为什么这里有歧义?与func(0.0)比较。
  • @tadman 这里不讲重载解析,只说名字查找,根据不合格查找
  • 我只是回应您的代码示例,您没有以不合格的方式使用它。也许你的意思是func(int i = 0)func(double i = 0.0) 其中func() 是不合格的?我不确定你的具体问题,措辞有点模糊。
  • @tadman 为什么您认为我的示例中的func(0) 没有以不合格的方式使用?
  • The lookup for an unqualified name used as the postfix-expression of a function call is described in [basic.lookup.argdep].

标签: c++ language-lawyer overload-resolution name-lookup


【解决方案1】:

合理的问题。相关部分是“按列出的顺序搜索范围以查找声明”。

在伪代码中

for (auto scope: scopes)
{
   if (scope.contains(name))
      return scope;
}
throw ill_formed(name);

一旦找到包含name 的范围,就会选择该范围。不会搜索列表中的其他范围。即使name 出现在该范围内,它也不会参与重载决议。

但是,在您的示例中,所选范围包含的不是一个而是两个 func 声明,因此仍然会发生重载决议。

【讨论】:

  • 一个很好的答案。你的意思是这些顺序列表是针对范围的吗?那么,如果这样,如何解释一个变量的名称在同一个范围内存在多个?如何隐藏之前的名字?谢谢
  • 正确;编译器首先创建一个候选范围的有序列表,然后逐个遍历这些范围,直到找到一个包含至少一个名称声明的范围。当然,一个变量名称在一个范围内最多只能出现一次。只有函数有重载。
  • 谢谢,我知道了
  • 另外,[basic.lookup.unqual] 的剩余部分是否可以描述这些候选作用域是什么?例如,“在全局作用域中使用的名称,在任何函数、类或用户声明之外命名空间,要在全局作用域使用前声明。”,意思是这个名字的“候选作用域”就是使用名字之前的全局作用域,对吧?
猜你喜欢
  • 2021-05-08
  • 2018-04-26
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多