12

考虑这段代码:

namespace foo {}

class A
{
   class B
   {
   };

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

namespace foo
{
   int bar( A::B& )
   {
   }
}

G++ 4.4.3 告诉我:

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

但我不能声明:

namespace foo
{
   int bar( A::B& );
}

在 A 类定义之前,因为 A::B 尚未声明。而且我显然不能声明“A类::B”,要声明BI类必须给出A类的定义,据我所知,“朋友”声明必须在A类的定义中。

对我来说奇怪的是,如果我将函数“bar()”从名称空间 foo 中取出,一切正常。对我来说,在命名空间内有一个函数或不在一个命名空间内会改变编译器是否接受类中的友元函数声明,这似乎违反直觉。

有没有人知道如何正确构建所有声明等以使其正常工作?

4

5 回答 5

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_);
}
于 2011-10-11T15:44:23.487 回答
0

相信你需要::foo::bar

于 2011-10-11T15:34:44.757 回答
0

你不能因为你不能前向声明内部类。

这是你将要得到的结局。

namespace foo {
    class A_B;
    int bar(A_B &);
}

struct A
{
   class B
   {
   };

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

namespace foo
{
   struct A_B : public A :: B {
     // constructors, delegated if you're C++11 :-)
   };

   int bar (A_B &)
   {
   }
}

你失去A::Bfoo::bar.

于 2011-10-11T15:38:07.420 回答
0

看起来你做不到。您可以做的是前向声明一个具有静态成员的类,并且该类获得友谊。但是每当你使用友谊时,至少再看看你的设计并问自己为什么。这可能很好,或者可能有更好的答案。

namespace foo { class bar; }

class A
{
   class B
   {
   };

   friend class ::foo::bar;
};

namespace foo
{
   class bar
   {
   public:
      static int run_bar( A::B& )
      {
      }
   };
}
于 2011-10-11T15:44:50.327 回答
0

您不能这样做,因为无法编写前向声明,A::B因此无法编写前向声明foo(A::B&)

但是,您可以使用称为“朋友名称注入”的技巧在类定义中声明(并可能定义)朋友函数。这样您就可以在没有命名空间限定符的情况下调用该友元函数(例如bar(b),而不是foo::bar(b)),并且依赖于参数的查找将成功解析调用:

struct A
{
    struct B {};

    friend int bar(B&) { // inject bar() into the outer namespace
        // implementation here
    }
};

namespace foo
{
   int foo()
   {
       A::B b;
       return bar(b); // it calls bar(B&) declared in A
   }
}
于 2011-10-11T17:46:37.570 回答