重载函数名查找

Overloaded function name lookup

本文关键字:查找 函数 重载      更新时间:2023-10-16

有三个例子:

i .

int foo(int i){ return 0; }
namespace A
{
    int foo();
    int a = foo(5);//Error: too many argument to function int a::foo()
}

namespace A
{
    int foo(int i){ return 0; }
    int foo(){ return 1; }
    int a = foo(5);//OK, Call A::foo(int)
}
第三

namespace A
{
    int foo(){ return 1; }
    int foo(int i){ return 0; }
    int a = foo(5);//OK, Call A::foo(int)
}

确定候选函数集的确切规则是什么?我认为(3.4.1/1)

名称查找在找到名称声明后立即结束。

尚不清楚在情况II和III中首先发现的是哪种声明(int foo(int)int foo()) ?

§佳绩重载,

当在同一作用域中为一个名字指定了两个或多个不同的声明时,就说这个名字超载。通过扩展,在同一作用域中声明相同名称但带有不同的类型被称为重载声明。只有函数和函数模板声明可以超载;变量和类型声明不能重载。

由于在同一命名空间中重载了函数声明,因此非限定名称查找查找到匹配的函数集并停止。(我承认这里的标准似乎有点不正确,因为它说"只要找到名称的声明"。)

因此对于IIIII,非限定名查找查找到同一组重载函数。

进一步扩展III

int foo(int i) { return 42; }
namespace A {
  int foo() { return 1; }
  int foo(int i) { return 0; }
  int a = foo(5); // OK, Call A::foo(int)
}

现在,看起来::foo(int)A::foo(int)可能是不明确的,但这并不是因为非限定名查找在找到A::foo()A::foo(int)后停止。然后由重载分辨率来选择最佳可行函数。

函数重载仅在函数位于同一命名空间时有效。也就是说,名称首先由名称空间查找,然后由函数签名查找。在情形1中,在a命名空间中有一个名为foo的函数,因此它尝试调用该函数,但是在该命名空间中没有foo 的定义,该定义接受整数形参。

在任何情况下,你都可以这样调用全局foo函数:

int a = ::foo(5);

双冒号,不带命名空间前缀,访问全局命名空间。