【问题标题】:Friend function with default argument inside struct in C++C ++中结构内具有默认参数的朋友函数
【发布时间】:2020-10-02 22:01:57
【问题描述】:

我有一个如下所示的结构:

struct Lip {
    int     x;

    friend Lip mkLip(Tester t, bool full = false);

    bool operator == (Lip p) const { return x == p.x; }
    bool operator != (Lip p) const { return x != p.x; }
    bool operator <  (Lip p) const { return x < p.x;  }
};

这个问题是它在 Mac 上抛出关于指定默认参数的朋友声明的错误。我读到一种方法是在某处有一个非朋友声明,但正如您所见,我的朋友函数具有与实际结构本身相同的返回类型。在这里解决这个问题的正确方法是什么?

【问题讨论】:

  • 你可以有一个返回Lip的成员函数。如果你想让它成为一个默认参数的朋友,你需要在类中定义它。

标签: c++


【解决方案1】:

你所有的成员都是public,所以你根本不需要friend

只要有一个漂亮、正常的函数声明:

struct Lip
{
    int x;

    bool operator==(Lip p) const { return x == p.x; }
    bool operator!=(Lip p) const { return x != p.x; }
    bool operator<(Lip p) const { return x < p.x; }
};

Lip mkLip(Tester t, bool full = false);

如果您随后引入该函数需要访问的private 成员,则以static 成员函数的形式将其设为工厂:

struct Lip
{
  private:
    int x;

  public:
    static Lip mkLip(Tester t, bool full = false);
    
    bool operator==(Lip p) const { return x == p.x; }
    bool operator!=(Lip p) const { return x != p.x; }
    bool operator<(Lip p) const { return x < p.x; }
};

static 成员函数可以访问实例的私有成员(例如,他们创建的一个!)。


如果除了使用mkLip 之外无法安全地构造它,您还应该考虑将类的构造函数设为private


注意向你的班级will lose it its aggregate status引入非staticprivate的东西;你可能关心也可能不关心。

【讨论】:

    【解决方案2】:

    你确实可以在类中给它一个定义:

    friend Lip mkLip(Tester t, bool full = false) { return {}; }
    

    但是,这会影响mkLip 上的名称查找。您可能希望mkLip 使用正常的查找规则并位于课堂之外。在这种情况下,您始终可以前向声明返回类型:

    // Before class
    struct Lip;
    Lip mkLip(Tester t, bool full = false);
    
    ...
    
    // Inside class
    friend Lip mkLip(Tester t, bool full);
    
    ...
    
    // After class
    Lip mkLip(Tester t, bool full) { return {}; }
    

    【讨论】:

    • 人们(包括我自己)确实倾向于忘记返回类型可能不完整,即使我们一直写 void foo(); ;)
    • 我看到 OP 已经投票并接受了(在 30 秒内!)。在这里拥有friend 仍然是完全没有意义和单一的,并且使代码的阅读方式比必要的更复杂。虽然这对于陷入该决定的人来说是正确的解决方案。
    猜你喜欢
    • 2012-11-03
    • 2021-11-14
    • 1970-01-01
    • 2018-04-08
    • 2017-09-27
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多