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

C++ C++;从命名空间内部对全局枚举的友元函数引用,c++,c++14,C++,C++14,以下用于FriendlyAccess的好友声明在C++98(gcc 4.4.7)下编译: typedef枚举我的错误 { 成功=0, 故障=1 }迈罗; MyError FriendlyAccess(); 命名空间外部{ 甲级 { 公众: friend MyError::FriendlyAccess();//枚举MyError不是类或命名空间 受保护的: int protectedMember(); }; }//为命名空间外部添加了缺少的终止符 使用outer::ClassA; int Clas

以下用于FriendlyAccess的好友声明在C++98(gcc 4.4.7)下编译:

typedef枚举我的错误
{
成功=0,
故障=1
}迈罗;
MyError FriendlyAccess();
命名空间外部{
甲级
{
公众:
friend MyError::FriendlyAccess();//枚举MyError不是类或命名空间
受保护的:
int protectedMember();
};
}//为命名空间外部添加了缺少的终止符
使用outer::ClassA;
int
ClassA::protectedMember()
{
返回0;
}
MyError FriendlyAccess()
{
甲级;
std::cout

当删除
::
时,您最终会声明另一个FriendlyAccess函数,这次是从
外部
命名空间中声明的。如果您将FriendlyAccess定义也放在工作区中,则此操作有效(然后您在全局命名空间中的初始声明未使用)

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

使用auto和trailing返回类型可以让它理解这是一个自由函数

friend auto ::FriendlyAccess() -> MyError;

删除
::
之前的
FriendlyAccess
。我真的不明白你是否因为遗留代码而故意使用c风格的定义…我猜
MyError::FriendlyAccess
只是忽略了空白,你会得到一个奇怪的解析…命名空间外部
应该在哪里结束?有在您的代码中没有关闭
}
。为
FriendlyAccess
使用尾随返回类型,假设
命名空间外部
的结尾正好在类的后面。
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()
friend auto ::FriendlyAccess() -> MyError;