如何组织 类 包含模板和朋友的混合?

How to organize classes containing mixture of templates and friends?

我有两个 C++ classes:

  1. 第一个 class 包含指向第二个 class 的指针,并具有通过指针调用第二个 class 的 public 方法的模板函数。由于是模板,该函数已在 class 声明中定义。
  2. 第二个class允许第一个class通过友谊机制访问其私人成员。

鉴于此,我的问题是:如何针对这种情况组织 sources/headers/forward 声明? 无论我尝试什么,它都不会编译成目标文件。

一个序列是这样的:

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

吠声 invalid use of incomplete type ‘class Class2’ 因为它无法识别 c2->Func();。 另一个是:

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

无法识别 friend void Class1::FuncFromClass1();

编译试为g++ -c -std=c++11 -Wall test.cpp.

请注意,如果可能的话,我宁愿不让 Class1 成为整个朋友,而是只想保留它的一种方法作为 Class2 的朋友。

此外,我还没有在 Windows 中尝试过 Visual Studio 中的完全相同的示例,但是看到了一个完全同构的情况,就像所描述的那样(在一个更大的项目中)并且没有收到任何投诉VS我记得。它是 g++ 独有的吗?

移动成员函数模板的实现,其中 Class2 的定义是已知的。

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

请注意,如果两个 类 都在一个 .h 文件中定义,则建议的解决方案很简单。如果 类 在单独的 .h 文件中定义,事情会变得有点复杂。您必须确保定义 Class1::DoSomething() 的 .h 文件在每个要使用 Class1::DoSomething().

的 .cpp 文件中是 #included