【发布时间】:2019-10-16 13:30:10
【问题描述】:
我目前正在移植一个迄今为止仅使用 Clang 构建的项目,也可以与 GCC 一起使用。该项目包含类似于下面的代码,并且可以使用 Clang 正常编译,但是 GCC 会给出错误消息。
class Outer
{
enum
{
ONE, TWO, THREE, COUNT
};
public:
class Inner
{
friend class Outer;
friend void somefunc()
{
int x = Outer::COUNT;
}
};
};
错误是:
<source>: In function 'void somefunc()':
<source>:15:32: error: 'Outer::<unnamed enum> Outer::COUNT' is private within this context
15 | int x = Outer::COUNT;
| ^~~~~
<source>:6:26: note: declared private here
6 | ONE, TWO, THREE, COUNT
| ^~~~~
注意somefunc 签名中的朋友关键字。删除它可以使代码用 GCC 编译得很好,我想知道哪个编译器是正确的?我的印象是友元函数与成员函数具有相同的访问权限,这将使其成为 GCC 错误。
【问题讨论】:
-
我认为主要问题是一旦你将
somefunc设为好友函数,它将失去对包含类的私有成员的自动访问权限。要么删除friend关键字,要么使sumefunc也成为Outer类的朋友。 (这样它就可以访问它的枚举。) -
@Gyebro 我明白了,所以你会说 GCC 是正确的,而 Clang 表现出不正确的行为?
-
@nitronoid 我认为 GCC 是正确的,因为友元函数的内联声明仍然被认为是在类范围之外。 Inline friend definitions。如果
somefunc是Outer的朋友,它会按预期工作:godbolt.org/z/3AkKUP -
我说这是一个 GCC 错误。如果
Inner可以访问Outer的私有成员,并且函数被命名为Inner的朋友,则访问控制应该可传递地工作。 -
@0x499602D2 这是我最初的感觉。
标签: c++ language-lawyer inner-classes friend access-control