它最近引起了我的注意 该成员的功能 完全 影子 类内时同名的自由函数。完全我的意思是,每个同名的免费函数根本不考虑重载解析。我可以理解为什么它是这样做的:

void f();

struct S
{
    void f();

    void g()
    {
        f(); // calls S::f instead of ::f
    }
};

当函数具有相同的签名时,其唯一的自然变量范围也以相同的方式工作。但是,为什么禁止明确的调用,其中自由功能具有不同的签名像这样:

void f();

struct S
{
    void f(int x);

    void g()
    {
        f(); // fails to compile attempting to call S::f, which has wrong signature
    }
};

我不是在问如何打电话给 阴影,阴影 类内部的自由函数。我想知道的是这个设计背后的基本原理。

有帮助吗?

解决方案

对于非限定名称查找,一次只考虑一个范围,如果该范围中的搜索没有产生任何结果,则搜索下一个更高的范围。在你的情况下,只有 S的范围进行搜索。

但是,为什么禁止明确的调用,其中自由功能具有不同的签名像这样:

问题是 名称查询 除了名字,什么都不关心。 标识符.它完全忘记了你想调用一个函数的事实,它只是看到一个标识符。相同的名称查找发生,如果你只是使用 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)
}
.

imo,这是疯狂的。

但为什么禁止禁止悬而未恒的呼叫,其中自由函数具有不同的签名,如下所示:

名称查找在重载过载决议之前发生:

  • 如果查找是模糊的,则没有完成重载分辨率。
  • 如果名称查找没有找到可行的函数,则尝试任何其他回合的查找。

规则是足够复杂的,没有“反馈”之间的重载和名称查找。我建议简化(如删除成员隐藏命名空间范围名称规则,并删除模糊名称查找)而不是复杂化。

我不能提供权威答案(也许有些人记得来自Design and Evolution of C++的引用或者当时实际上已经在委员会上),但我的第一次猜测是在你所表现的情况下完全失败。很容易忘记某些时间有多少件事。另外,过载解决方案可能非常复杂,并且可能存在默认的参数和转换。所以我宁愿在这种情况下拥有最有限的范围,以始终确定正在调用什么。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top