最近它来到我的注意力成员函数完全里面的类时,无阴影函数具有相同的名称。 而通过完全我的意思是具有相同名称的每一个自由的功能不被认为是用于重载的。 我可以理解为什么它与somwthing这样做:
void f();
struct S
{
void f();
void g()
{
f(); // calls S::f instead of ::f
}
};
其中函数具有相同的特征,其只是自然的,因为变量的作用域的工作方式相同。 但是,为什么禁止unambigious调用其中免费功能具有不同的签名是这样的:
void f();
struct S
{
void f(int x);
void g()
{
f(); // fails to compile attempting to call S::f, which has wrong signature
}
};
我不问如何从类中调用一个阴影免费功能。 我想知道的是这种设计背后的基本原理。
对于不合格的名称查找,只能有一个时间范围考虑,如果在该范围内搜索没有任何结果,下一个更高的范围搜索。 在你的情况下,只有S
的范围搜索。
但是,为什么禁止unambigious调用其中免费功能具有不同的签名是这样的:
问题是, 名称查找不与任何东西,但名称, 标识关注自身。 这是完全没有注意到要调用一个函数的事实,它只是看到一个标识符。 同样的名称查找发生,如果你只是用auto x = f;
,如果你觉得这样的说法,也有你只想要一个非常有限的范围内搜索很好的理由。 别的只想惊喜的用户。
有一种特殊的,非常令人惊讶的,规则(但它并不适用于你的例子)指出,一旦类成员名称由名称查找发现,没有命名空间范围内搜寻:
#include <string>
struct C {
std::string s;
explicit C (std::string);
void swap (C& rhs) {
swap (s, rhs.s); // error: swap is C::swap
}
};
void swap (C& lhs, C& rhs) {
swap (lhs.s, rhs.s); // std::swap(string,string)
}
国际海事组织,这是疯狂。
但是,为什么禁止unambigious调用其中免费功能具有不同的签名是这样的:
名称查找重载解析之前发生:
- 如果查询是不明确的,超载的分辨率没有这样做。
- 如果按名称查询发现没有可行的功能,没有其他一轮查找的是尝试。
规则是不超载的名称查找之间的“反馈” 足够复杂 。 我建议简化(如删除成员隐藏命名空间范围名称规则,并去除模糊的名称查找),而不是复化。
我不能提供一个权威的答案(也许有些记得报价Design and Evolution of C++
或实际上已对委员会在那个时候),但我的第一个猜测是因为你表现出的情况下准确地失败。 这是很容易忘记有多少事情是在范围上在一定的时间。 此外重载可以很复杂,有可能是默认参数和转换。 所以,我宁愿在这种情况下,最有限的范围总是知道究竟是被称为什么。