首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >错误:嵌套名称说明符中使用的类型不完整

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

Stack Overflow用户
提问于 2011-01-01 05:57:53
回答 3查看 36.9K关注 0票数 20

有两个非模板类AB有一些静态模板方法。

A类调用B中的静态方法,从B类调用A的静态方法。源代码只是为了说明(不是真正的代码)。

A.h

代码语言:javascript
复制
#include "B.h"
class A 
{
 public:
   template <class T>
   void f1 ()
   {
      T var1= ...;
      T var2 = B::f4(T);
   }

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

#include "A.h"
class B
{
 public:
   template <class T>
   void f3 ()
   {
      T var1= ...;
      T var2 = A::f2(T); //Error
   }

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

我在使用NetBeans中的g++编译器时遇到了问题。编译过程中出现以下错误:错误:嵌套名称说明符g++中使用的类型A不完整。

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

有一个更老的bug:

http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg01383.html

EN

回答 3

Stack Overflow用户

发布于 2011-01-01 06:17:38

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

代码语言:javascript
复制
class A
{
public:
  template <class T>
  void f1();
};

class B
{
  ...
};

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

如果您坚持对A和B使用单独的头文件(这实际上不会有任何区别,因为它们最终会包含彼此),那么您将需要重新构造它们,以便其中一个头文件不包括另一个头文件,因此至少需要在一个单独的文件中定义一个依赖的模板函数。例如:

代码语言:javascript
复制
// 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
}
票数 7
EN

Stack Overflow用户

发布于 2011-01-01 06:18:33

因为存在循环依赖,所以需要仔细安排类AB的声明,以便在定义成员函数之前声明它们。

这是A.h

代码语言:javascript
复制
#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

这是B.h

代码语言:javascript
复制
#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.hB.h,而不会出现问题。

票数 5
EN

Stack Overflow用户

发布于 2011-01-01 06:05:16

您的问题是循环标头依赖。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4572483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档