Search code examples
c++friend-function

Bilateral friend functions in C++: how to make it compile?


I have the following C++ files:

A.h


#ifndef A_H
#define A_H

#include "B.h"

class A
{
    private:
        int m_a;
    public:
        A();

        void a(const B &b);

    friend void B::b(const A &a);
};

#endif // A_H

A.cpp


#include "A.h"
#include "B.h"
#include 

A::A()
{
    m_a = 100;
}

void A::a(const B &b)
{
    std::cout << b.m_b << ".\n";
}

B.h


#ifndef B_H
#define B_H

class A;

class B
{
    private:
        int m_b;
    public:
        B();
        void b(const A &a);

    friend void A::a(const B &b); // error: invalid use of incomplete type 'class A'
};

#endif // B_H

B.cpp


#include "B.h"
#include 
#include "A.h"

B::B()
{
    this->m_b = 101;
}

void B::b(const A &a)
{
    std::cout << a.m_a << ".\n";
}

When I try to compile this, it gives me:

error: invalid use of incomplete type 'class A'.

How should I fix this?


Solution

  • It is not possible to have a member functiion of B a friend of A and a member function of A a friend of B.

    There are several ways to overcome this.

    1. Write one or both functions as non-members. Make them friends of both classes if neseccary.
    2. Make the entire class a friend of the other class. If that's too broad a permission, extract a smaller class to serve as a friend.
    3. Turn both classes into class templates (the template parameter does not matter).

      enum unit {u};
      
      template <unit X> class A;
      
      template <unit X> class B
      {
          static void foo() {}
          static void bar() { A<X>::foo(); }
          friend void A<X>::bar();
      };
      
      template <unit X> class A
      {
          static void foo() {}
          static void bar() { B<X>::foo(); }
          friend void B<X>::bar();
      };
      
      using AX = A<u>;
      using BX = B<u>;