相关疑难解决方法(0)

朋友声明的复杂范围规则有什么意义?

我最近发现朋友声明范围遵循极其特殊的规则 - 如果你有一个friend函数或一个尚未声明的类的声明(定义),它会在直接封闭的命名空间中自动声明(定义),它是不可见的不合格和合格的查询; 但是,友元函数声明通过依赖于参数的查找保持可见.

struct M {
    friend void foo();
    friend void bar(M);
};

void baz() {
    foo();    // error, unqualified lookup cannot find it
    ::foo();  // error, qualified lookup cannot find it
    bar(M()); // ok, thanks to ADL magic
}
Run Code Online (Sandbox Code Playgroud)

如果你看一下标准(参见链接的答案),他们就会付出很大的代价来启用这种古怪的行为,在复杂规则的限定/非限定查找中添加一个特定的例外.最终的结果让我感到非常困惑1,还有另一个案例要添加到实现中.作为

  • 要求friend声明引用现有名称,期限; 要么
  • 允许他们像现在一样声明东西,但不改变普通的名字查找(因此,这样的名称变得可见,好像在封闭的命名空间中声明为"正常")

似乎更容易实现,指定,最重要的是,理解,我想知道:为什么他们为这个烂摊子烦恼?他们试图覆盖哪些用例?在任何这些更简单的规则下(特别是第二个与现有行为最相似的规则)会破坏什么?


  1. 例如,在这种特殊情况下

    struct M {
       friend class N;
    };
    N *foo;
    typedef int N;
    
    Run Code Online (Sandbox Code Playgroud)

    你得到可笑的精神分裂症错误信息

    <source>:4:1: error: 'N' does not name …
    Run Code Online (Sandbox Code Playgroud)

c++ friend language-history friend-function language-lawyer

11
推荐指数
1
解决办法
221
查看次数