【问题标题】:forward declaration of global friend function全局友元函数的前向声明
【发布时间】:2013-02-27 14:54:55
【问题描述】:

我有以下命名空间和类层次结构:

namespace Ns1 {
    class Outer {
    private:
           class Inner {
           };
           QSet<Inner> set;
    };
}

现在我需要声明一个全局函数:

uint qHash(Ns1::Outer::Inner const& el);
bool operator==(Ns1::Outer::Inner const& el1,
                Ns1::Outer::Inner const& el);

所以函数必须是 Outer 和 Inner 的朋友。 问题并表明该函数在全局范围内:

friend uint qHash(Ns1::Outer::Inner const& el);
friend operator==(Ns1::Outer::Inner const& el1,
                Ns1::Outer::Inner const& el);

我无法处理这种情况下的前向声明。有什么解决办法吗?

【问题讨论】:

  • 为什么这个函数需要是一个“全局”函数?我认为问题本身就在这里。如果它可以接受的参数是Ns1::Outer::Inner,那么我认为在命名空间Ns1 之外创建函数没有任何意义。鉴于InnerprivateOuter,我也认为将其设为非成员函数没有任何意义。
  • 请。问题就是我所说的问题。不要做你个人的假设。如果存在,请给出解决方案。
  • 如果Inner 是私有的,你想如何获取Inner 对象以将其传递给函数?这看起来像是一个设计问题——就像friend 的许多用途一样。不,您不需要 f 成为 Inner 的朋友 - 除非它使用它的私有/受保护方法。
  • @user14416:解决方案可能不存在,因为您做出了错误的个人假设。
  • 如果您在上下文中提供了一个带有friend 声明的组合示例,将会更加清晰。这也是定义吗?当它已经被 ADL 发现并且是​​大型重载集的一部分时,为什么还需要在命名空间范围内声明它?

标签: c++ qt friend forward-declaration


【解决方案1】:

编辑:

你是对的!您发现了该语言无法处理的极端情况(因为 friendship 声明仅适用于先前声明的函数或最里面的命名空间)。不幸的是,这意味着您将不得不稍微重构您的代码,因为您想要做的事情不能完全以这种方式完成。

最简单的方法是在Ns1命名空间中定义这两个函数,然后将using它们放到全局命名空间中。这基本上与您想要的效果完全相同,只是嵌套命名空间中有两个额外的函数。

您的另一组选项涉及从根本上解决问题:为什么您的类对象的公共接口没有提供足够的能力,以至于需要友谊?例如,如果您希望能够在全局范围内传递 Inner 对象,为什么 InnerOuter 中是私有的?

为什么哈希和比较函数需要访问Inner 的内部状态?为什么不让Inner 提供一个公共的比较接口,然后由运营商使用?

【讨论】:

  • 实际上这并不能解决问题,因为如果您使用 :: 限定函数显然需要已经声明函数。而且您不能前向声明它们,因为它们的签名需要 Outer 的完整定义。似乎是语言缺陷。
猜你喜欢
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
相关资源
最近更新 更多