提问人:Enlico 提问时间:8/26/2022 更新时间:8/27/2022 访问量:89
[over.load]/1 中的注释有什么意义?
What's the relevance of the Note in [over.load]/1?
问:
(你可能会把这个问题看作是这个问题的重复,但是,老实说,我还没有真正理解这个问题,所以我用我自己的措辞单独问。
[over.load]/1 显示:
并非所有函数声明都可以重载。此处指定了那些不能超载的内容。如果程序在同一作用域中包含两个这样的不可重载声明,则该程序的格式不正确。[注:此限制适用于作用域内的显式声明,以及此类声明与通过使用声明进行的声明之间的显式声明。它不适用于由于名称查找(例如,由于 using 指令)或重载解析(例如,对于运算符函数)而产生的函数集。— 尾注]
作为一个临时问题,我说“此限制”是指“并非所有函数声明都可以重载”这一事实是否正确?
如果是这样的话,那么我会推断,如果我创建一组“由于名称查找而制造的函数”的情况,那么即使它们在上面引用的段落后面的列表中指定,这些函数也可以重载,因为限制不适用。
但这到底意味着什么,知道它有什么用呢?
我非常清楚,我不能重载函数仅在返回类型上有所不同,正如这个错误的代码所证明的那样,
int f() { return 1; };
double f() { return 2; }; // compile-time error
而且我也知道,如果两个 s 中的一个在另一个命名空间中,但通过声明引入,也会发生相同的情况f
using
int f() { return 1; };
namespace n {
double f() { return 2; };
}
using n::f; // compile-time error
我认为上面的第一个片段是作用域中显式声明的示例,而第二个代码片段是此类声明和通过 using
声明进行的声明之间的示例。
但是,由于名称查找(例如,由于 using 指令)而制造的函数示例是什么?像这样的东西?
int f() { return 1; };
namespace n {
double f() { return 2; };
}
using namespace n; // no error, as n::f can be seen by name lookup, but it's not actually declared here
如果是这样的话,我应该从中推断出什么?该限制不适用,因此我可以重载这 2 个函数。这是什么意思?我写完上面的 5 行片段后,是否已经超载了它们?或者我需要打一个电话,比如?不过,在这种情况下,调用是模棱两可的。auto x = f()
我真的不明白那张纸条想说什么。
答:
在使用 using 指令的示例中,函数不会重载。重载在 [over.pre]/1 中定义:
当为同一作用域中的单个名称指定两个或多个不同的声明时,该名称被称为重载,并且这些声明称为重载声明。...
两者不在同一范围内,因此它们不会过载。f
但是,如果尝试调用 ,则将从名称查找的结果形成一个重载集,并且它包含两个声明。总是制造过载集;它是在使用名称时创建的(而不仅仅是声明);这种制造可能会将多个功能带入同一个过载集,尽管这些功能相互过载是非法的。该注释指出,创建这样的重载集并非格式错误。f
f
当然,过载解决可能不明确,导致程序格式不正确,但有一些方法可以使用格式正确的重载集。例如,以下为 A-OK:
int f() { return 1; };
namespace n {
double f() { return 2; };
}
using namespace n;
double (*fp)() = &f;
评论