在GodBolt.org上测试时,此代码在MSVC上编译,但不在GCC上编译
Baz类是在匿名 namespace 中声明的,这使GCC认为它是与我在下面定义的类不同的类,但MSVC似乎将它们连接起来。
namespace { class Baz; }
class Foo { protected: int x; };
class Bar : public Foo { friend class Baz; };
namespace {
class Baz { void f() { Bar b; b.x = 42; } };
}
根据标准正确的是什么?
最佳答案
问题在于,您正在为友元声明使用精心设计的类型说明符,而GCC则使用它在全局 namespace 中声明类Baz
。 An elaborated type specifier is a declaration unless a previous declaration is found in the inner most enclosing namespace。显然尚不清楚Baz
的声明是否应视为在全局命名空间中。
要解决此问题,只需在好友声明中使用类的名称即可:
namespace { class Baz; }
class Foo { protected: int x; };
class Bar : public Foo { friend Baz; };
namespace {
class Baz { void f() { Bar b; b.x = 42; } };
}
在 friend 声明中使用详尽的类型说明符是一种习惯性的病理习惯。除非类型名称也是变量名称,否则没有理由使用详细的类型说明符。
关于c++ - GCC不喜欢使用匿名命名空间转发声明来结交 friend ,但是MSVC愿意。什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63397661/