C++ 错误:嵌套名称说明符中使用的类型不完整

C++ 错误:嵌套名称说明符中使用的类型不完整,c++,g++,C++,G++,有两个非模板类A,B具有一些静态模板方法 从类A调用B中的静态方法,从类B调用A中的静态方法。源代码仅用于说明(非真实代码) A.h #包括“B.h” 甲级 { 公众: 模板 无效f1() { T var1=。。。; T var2=B::f4(T); } 模板 T f2() { 返回。。。 } }; #包括“A.h” B类 { 公众: 模板 无效f3() { T var1=。。。; T var2=A::f2(T);//错误 } 模板 T f4() { 返回。。。 } }; 我在NetBeans

有两个非模板类
A
B
具有一些静态模板方法

从类
A
调用
B
中的静态方法,从类
B
调用
A
中的静态方法。源代码仅用于说明(非真实代码)

A.h

#包括“B.h”
甲级
{
公众:
模板
无效f1()
{
T var1=。。。;
T var2=B::f4(T);
}
模板
T f2()
{
返回。。。
}
};
#包括“A.h”
B类
{
公众:
模板
无效f3()
{
T var1=。。。;
T var2=A::f2(T);//错误
}
模板
T f4()
{
返回。。。
}
};
我在NetBeans中使用g++编译器时遇到问题。编译过程中发生以下错误:错误:嵌套名称说明符g++中使用的类型A不完整

我试图将前向声明添加到这两个类中,但都没有成功

有一个更老的bug:


您的问题是循环头依赖。

头文件之间存在循环依赖关系。由于您的类是如此紧密地交织在一起,我建议将它们合并到一个头文件中,结构如下:

class A
{
public:
  template <class T>
  void f1();
};

class B
{
  ...
};

template <class T>
void A::f1()
{
  // Use full definition of class B
}
A类
{
公众:
模板
void f1();
};
B类
{
...
};
模板
void A::f1()
{
//使用B类的完整定义
}
如果您坚持对A和B使用单独的头文件(由于它们最终相互包含,因此不会产生任何区别),则需要重新构造它们,使其中一个头文件不包含另一个头文件,因此至少需要在单独的文件中定义一个从属模板函数。例如:

// File "a_no_b.h"
class A
{
public:
  template <typename T>
  void f1();
};

// File "b_no_a.h"
class B
{
public:
  template <typename T>
  void f3();
};

// File "a.h"
#include "a_no_b.h"
#include "b_no_a.h"

template <typename T>
void A::f1()
{
  // Use full definition of class B
}

// File "b.h"
#include "b_no_a.h"
#include "a_no_b.h"

template <typename T>
void B::f3()
{
  // Use full definition of class A
}
//文件“a\u no\u b.h”
甲级
{
公众:
模板
void f1();
};
//文件“b_no_a.h”
B类
{
公众:
模板
void f3();
};
//文件“a.h”
#包括“a_no_b.h”
#包括“b_no_a.h”
模板
void A::f1()
{
//使用B类的完整定义
}
//文件“b.h”
#包括“b_no_a.h”
#包括“a_no_b.h”
模板
void B::f3()
{
//使用A类的完整定义
}

由于存在循环依赖关系,因此需要仔细安排类
a
B
的声明,以便在定义成员函数之前声明它们

这里是A.h
A.h

#ifndef A_H
#define A_H 1
class A 
{
 public:
     template <class T>
     void f1 ();

     template <class T>
     T f2();
};

#include "B.h"

template <class T>
void A::f1()
{
     T var1= ...;
     T var2 = B::f4(T);
}

template <class T>
T A::f2()
{
     return ...
}

#endif
#ifndef B_H
#define B_H 1
class B
{
 public:
     template <class T>
     void f3 ();

     template <class T>
     T f4();
};

#include "A.h"

template <class T>
void B::f3()
{
     T var1= ...;
     T var2 = A::f2(T);
}

template <class T>
T B::f4()
{
     return ...
}

#endif

使用此方法,您将能够首先包含
A.h
B.h
,而不会出现问题。

谢谢,它工作得很好。在类声明之前,我有两个include指令……谢谢,它工作得很好。我已经在类声明之前包含了这两个指令……那些否决的人需要声明他们反对的内容。因为这是对OP问题的正确回答。OP没有要求解释如何解决循环头依赖关系,这些琐事在每本书中都有解释。
#ifndef B_H
#define B_H 1
class B
{
 public:
     template <class T>
     void f3 ();

     template <class T>
     T f4();
};

#include "A.h"

template <class T>
void B::f3()
{
     T var1= ...;
     T var2 = A::f2(T);
}

template <class T>
T B::f4()
{
     return ...
}

#endif