如何在命名空间中声明一个以内部类作为参数的友元函数?
考虑这段代码:
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 尚未声明。显然,我不能声明“class A::B”,要声明类 BI 必须给出类 A 的定义,并且据我所知,“friend”声明必须位于类 A 的定义内
。对我来说奇怪的是,如果我从命名空间 foo 中取出函数“bar()”,一切都会正常。对我来说,在命名空间内或不在命名空间内的函数会改变编译器是否接受类中的友元函数声明,这似乎违反直觉。
有谁知道如何正确构建所有声明等以使其发挥作用?
Consider this code:
namespace foo {}
class A
{
class B
{
};
friend int foo::bar( B& );
};
namespace foo
{
int bar( A::B& )
{
}
}
G++ 4.4.3 tells me:
friendfun-innerclass.cpp:21: error: 'int foo::bar(A::B&)' should have
been declared inside 'foo'
But I can't declare:
namespace foo
{
int bar( A::B& );
}
before the class A definition because A::B hasn't been declared. And I can't declare "class A::B" obviously, to declare class B I have to give the definition of class A, and as far as I know the "friend" declarations have to be inside the definition of class A.
What's strange to me is that if I take function "bar()" out of namespace foo everything works fine. It seems counterintuitive to me that having a function inside a namespace or not inside a namespace changes whether the compiler will accept a friend function declaration in the class.
Does anybody know of a way to proprerly structure all the declarations and such to get this to work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
无法按照您想要的方式完成,因为您必须转发声明嵌套类(你不能),以便为
foo::bar
提供原型。作为解决这个问题的第一次尝试,我可能会求助于将 foo::bar 制作为函数模板。这样,编译器将在知道
A
和B
后解析类型。测试线束:
Can't be done the way you want to, because you would have to forward declare a nested class (which you can't) in order to provide a prototype for
foo::bar
.As a first attempt to get around this problem, I would probably resort to making
foo::bar
a function template. That way the compiler will resolve the types afterA
andB
are known.Test harness:
我相信您需要
::foo::bar
。I believe that you need
::foo::bar
.你不能,因为你不能前向声明内部类。
这就是你将要得到的结束。
您失去了
A::B
的私有性,但如果您仔细想想,这是有道理的,否则您将无法实现foo::bar
。You can't because you can't forward-declare inner classes.
This is a close as you're gonna get.
You lose privatehood of
A::B
, but if you think about it, that makes sense, or you wouldn't be able to implementfoo::bar
.看起来你做不到。你可以做的是向前声明一个带有静态成员的类,并且该类获得友谊。但任何时候你使用友谊时,至少要再看看你的设计并问自己为什么。可能没问题,或者可能有更好的答案。
It doesn't look like you can do that. What you can do is forward declare a class with a static member, and the class gets friendship. But any time you use friendship at least take one more look at your design and ask yourself why. It may be fine or there may be a better answer.
您不能这样做,因为无法编写
A::B
的前向声明,因此无法前向声明foo(A::B&)
。但是,您可以使用称为“友元名称注入”的技巧在类定义中声明(并可能定义)友元函数。这样,您就可以在没有命名空间限定符的情况下调用该友元函数(例如
bar(b)
而不是foo::bar(b)
),并且参数相关的查找将成功解析称呼:You can't do it because there is no way to write a forward declaration of
A::B
and hence forward declarefoo(A::B&)
.However, you can use a trick known as "friend name injection" to declare (and possibly define) a friend function in the class definition. This way you can call that friend function without namespace qualifiers (e.g.
bar(b)
instead offoo::bar(b)
) and argument-dependent lookup will successfully resolve the call: