【发布时间】:2020-04-15 10:02:29
【问题描述】:
我知道下面的 C++ 代码 sn-p 应该会在 g 的定义中产生错误,因为 p.t.x 是私有的,不能在那里访问。
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p);
};
void g(P &p) { p.t.x = 42; }
让我困惑的是下一个sn-p。不同之处仅在于友元函数g 的定义 现在出现在内部 类P。
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p) { p.t.x = 42; }
};
Clang++(6.0.0-1ubuntu2 和 Apple 版本 clang-1100.0.33.8)编译后者没有错误,而 GNU C++(7.5.0-3ubuntu1~18.04)产生与前者相同的错误 sn-p .
我了解后一种情况下定义的函数g不在同一个范围内
正如前者中定义的那样(参见related question 和older longer discussion),它只能通过 ADL 看到。但我认为我在这里问的是不同的:T 类中的声明 friend class P 是否应该扩展到朋友函数 g 的主体?
C++ 标准的相关部分(最近的drafts 中的 §11.3 或 §11.9.3)指出:
7 ... 类中定义的友元函数在(词法)范围内 定义它的类。外部定义的友元函数 该类不是(6.5.1)。
所以我知道 Clang++ 和 GNU C++ 对“词法范围”的含义有不同的解释(另请参阅 this answer 到上一个相关问题)。 Clang++ 似乎编译 g 就好像它是类 T 的朋友,可能是因为它在类 P 的词法范围内,这是类 T 的朋友,而 GNU C++ 没有。
- 两个编译器之一是否存在错误?
- 如果是,是哪一个?
- 不管前面问题的答案如何,这不是标准应该更好地形式化的东西吗?
【问题讨论】:
-
@Scheff 指出的other question 相似,因为它显示了 Clang++ 和 GNU C++ 解释标准的方式不同,(恕我直言)可能更清楚。然而,歧义的对象在这里有所不同。
标签: c++ g++ language-lawyer clang++ friend-function