【问题标题】:Error: incomplete type used in nested name specifier错误:嵌套名称说明符中使用的类型不完整
【发布时间】:2010-12-31 21:57:52
【问题描述】:

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

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

啊.h

#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不完整。

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

有一个较旧的错误:

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

【问题讨论】:

    标签: c++ g++


    【解决方案1】:

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

    class A
    {
    public:
      template <class T>
      void f1();
    };
    
    class B
    {
      ...
    };
    
    template <class T>
    void A::f1()
    {
      // Use full definition of class 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
    }
    

    【讨论】:

    • 谢谢,它运作良好。我在类声明之前都有两个包含指令......
    【解决方案2】:

    由于存在循环依赖,需要仔细安排类AB的声明,使它们都在定义成员函数之前声明。

    这里是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
    

    这里是B.h

    #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 而不会出现问题。

    【讨论】:

    • 谢谢,它运作良好。我在类声明之前都有两个包含指令......
    【解决方案3】:

    你的问题是循环头依赖。

    【讨论】:

    • 投反对票的人需要说明他们反对什么。因为它是对 OP 问题的正确答案。 OP 没有要求解释如何解决循环头依赖关系,每本书都解释了这些琐碎的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多