C++友元函数从命名空间内部引用全局枚举



FriendlyAccess的以下友元声明在C++98(gcc 4.4.7(下编译:

typedef enum MyError
{
SUCCESS = 0,
FAILURE = 1
} MyError;
MyError FriendlyAccess();
namespace outer {
class ClassA
{
public:
friend MyError ::FriendlyAccess();  // enum MyError is not a class or namespace
protected:
int protectedMember();
};
} // Added missing terminator for namespace outer
using outer::ClassA;
int
ClassA::protectedMember()
{
return 0;
}
MyError FriendlyAccess()
{
ClassA a;
std::cout << "Access Protected Method " << a.protectedMember() << std::endl;
return SUCCESS;
}

友元声明中的枚举引用不会在C++14(gcc 8.3.1(下编译:

friend.cpp:17:37: error: ‘enum MyError’ is not a class or a namespace
friend MyError ::FriendlyAccess();
^
friend.cpp:17:37: error: ISO C++ forbids declaration of ‘FriendlyAccess’ with no type [-fpermissive]
friend.cpp: In function ‘MyError FriendlyAccess()’:
friend.cpp:38:66: error: ‘int outer::ClassA::protectedMember()’ is protected within this context
std::cout << "Access Protected Method " << a.protectedMember() << std::endl;
^
friend.cpp:29:1: note: declared protected here
ClassA::protectedMember()

在全局命名空间中声明ClassA允许代码成功编译。在C++的后续版本中,是否有正确的方法从友元声明的命名空间内部引用C样式枚举?

更新

  • C样式枚举是遗留代码

  • 添加了缺失的"}"命名空间外部的终止符

  • 删除":"全局范围分隔符允许编译友元声明,但将友谊授予outer::FriendlyAccess而不是

  • IICapitano建议的尾随返回类型确实成功编译了

    好友auto::FriendlyAccess((->MyError;

friend语句采用函数声明或定义。

当删除::时,您最终会声明另一个FriendlyAccess函数,这次是从outer命名空间内部声明的。如果您也将FriendlyAccess定义放在工作空间中(那么您在全局命名空间中的初始声明是未使用的(,则会起作用。

编译器似乎将friend MyError ::FriendlyAccess();解释为试图与MyError类的成员方法交朋友(这是合法的(,并且没有发现它也可能是您现有的自由函数。

使用自动和尾随返回类型使其了解这是一个免费功能

friend auto ::FriendlyAccess() -> MyError;

最新更新