0

I have two C++ classes such that:

  1. The first class contains a pointer to the second class and has template function that calls second class's public method through a pointer. The function is defined already in the class declaration, for the reason of being a template.
  2. The second class allows the first class to access its private members through friendship mechanism.

Given that, my question is: how do I organize the sources/headers/forward declarations for this situation? Whatever I tried, it just doesn't compile to an object file.

One sequence is this:

class Class2;

class Class1
{
        Class2 * c2;
public:
        template<typename T> T DoSomething(T& X)
        {
                c2->Func();
                return X;
        };

        void FuncFromClass1();

};

class Class2
{
        int data;
public:
        Class2() : data(0) {};
        void Func();
        friend void Class1::FuncFromClass1();
};

void Class2::Func()
{
        int i;
}

void Class1::FuncFromClass1()
{
        int j;
        c2 = new Class2;
        c2->data = 1;
}

Barks invalid use of incomplete type ‘class Class2’ because it doesn't recognize c2->Func();. The other one is:

class Class1;

class Class2
{
        int data;
public:
        Class2() : data(0) {};
        void Func();
        friend void Class1::FuncFromClass1();
};

class Class1
{
        Class2 * c2;
public:
        template<typename T> T DoSomething(T& X)
        {
                c2->Func();
                return X;
        };

        void FuncFromClass1();

}; 

void Class2::Func()
{
        int i;
}

void Class1::FuncFromClass1()
{
        int j;
        c2 = new Class2;
        c2->data = 1;
}

Doesn't recognize friend void Class1::FuncFromClass1();.

The compilation is tried as g++ -c -std=c++11 -Wall test.cpp.

Note I'd rather not make Class1 as entire friend, rather want to keep only one of its methods as a friend to Class2, if at all possible.

Also, I haven't tried the exact same example in Visual Studio in Windows, but saw an entirely isomorphic situation like the one described (within a bigger project) and no complaints came from VS as far as I recall. Is it unique to g++?

MajinSaha
  • 188
  • 1
  • 9
  • Since `c2->Func();` does not use the template parameter, you code move that to a regular member function. – R Sahu May 16 '18 at 05:35
  • @RSahu It's just a very simplified example. I need to keep it there in my actual big project! – MajinSaha May 16 '18 at 05:36

1 Answers1

1

Move the implementation of the member function template where definition of Class2 is known.

class Class2;

class Class1
{
   private:
      Class2 * c2;
   public:

      // Delcare, don't define
      template<typename T> T DoSomething(T& X);

      void FuncFromClass1();

};

class Class2
{
   private:
      int data;
   public:
      Class2() : data(0) {};
      void Func();
      friend void Class1::FuncFromClass1();
};

// Define
template<typename T>
T Class1::DoSomething(T& X)
{
   c2->Func();
   return X;
};

Note that the proposed solution is simple if both classes are defined in one .h file. If the classes are defined in separate .h files, things get a little bit more complex. You'll have to make sure that the .h file where Class1::DoSomething() is defined is #included in every .cpp file where you want to use Class1::DoSomething().

R Sahu
  • 204,454
  • 14
  • 159
  • 270