如何在以内部类作为参数的命名空间中声明友元函数?

Jay*_*ker 12 c++ inner-classes forward-declaration friend-function

考虑以下代码:

namespace foo {}

class A
{
   class B
   {
   };

   friend int foo::bar( B& );
};

namespace foo
{
   int bar( A::B& )
   {
   }
}
Run Code Online (Sandbox Code Playgroud)

G ++ 4.4.3告诉我:

friendfun-innerclass.cpp:21:错误:'int foo :: bar(A :: B&)'应该在'foo'中声明

但我无法宣布:

namespace foo
{
   int bar( A::B& );
}
Run Code Online (Sandbox Code Playgroud)

在A类定义之前因为A :: B尚未声明.而且我不能明确声明"A类:: B",声明类BI必须给出类A的定义,据我所知,"朋友"声明必须在A类的定义中.

对我来说很奇怪的是,如果我从命名空间foo中取出函数"bar()",一切正常.对我来说似乎违反直觉的是,在命名空间内部或不在命名空间内部使用函数会改变编译器是否接受类中的友元函数声明.

有没有人知道如何通过这种方式来构建所有声明并使其发挥作用?

Joh*_*ing 3

无法按照您想要的方式完成,因为您必须转发声明一个嵌套类(您不能这样做)才能为foo::bar.

作为解决这个问题的第一次尝试,我可能会求助于制作foo::bar一个函数模板。这样编译器将解析已知之后的A类型B

测试线束:

namespace foo
{
    template<class B> int bar(B&);
};

class A
{
   class B
   {
       template<class B> friend int foo::bar( B& );
       int n_;
   public:
       B() : n_(42) {}
   };

public:
    B b_;
};

template<class B> int foo::bar(B& b)
{
    return b.n_;
}

int main()
{
    A a;
    foo::bar(a.b_);
}
Run Code Online (Sandbox Code Playgroud)