terett
terett

Reputation: 447

Friend function with default argument inside struct in C++

I have a struct that looks like this:

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;  }
};

The problem with this is that it throws error on Mac regarding the friend declaration specifying a default argument. I read that one way is to have a non-friend declaration somewhere out, but as you can see my friend function has the same return type as the actual struct itself. What's the proper way to fix this here?

Upvotes: 0

Views: 99

Answers (2)

Qaz
Qaz

Reputation: 61920

You can indeed give it a definition inside the class:

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

However, this will affect name lookup on mkLip. Chances are you want mkLip to use normal lookup rules and lie outside of the class. In this case, you can always forward-declare the return type:

// 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 {}; }

Upvotes: 1

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

All your members are public, so you don't need a friend at all.

Just have a nice, normal function declaration:

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);

If you then introduce private members that the function needs access to, make it a factory in the form of a static member function:

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 member functions have access to private members of an instance (e.g. one that they create!).


You should also consider making the class's constructor private if it can't be safely constructed except when using mkLip to do so.


Note that introducing non-static private things to your class will lose it its aggregate status; you may or may not care.

Upvotes: 1

Related Questions