2010-12-31 11 views
19

2つの非テンプレートクラスA,Bにはいくつかの静的テンプレートメソッドがあります。 B内のクラスA静的メソッドからエラー:ネストされた名前指定子に不完全な型が使用されました

が呼び出され、AからクラスからB静的メソッドが呼び出されます。説明のみ(ない実際のコード)のソースコード...

A.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

答えて

0

あなたの問題は、円形のヘッダの依存関係である:

は古いバグがあります。

+29

解決策は...? –

+1

downvotingする人は、彼らが反対するものを述べる必要があります。 OPの質問に対する正解ですから。 OPは、循環ヘッダーの依存関係を解決する方法を説明するよう求めなかったが、これらの問題はすべての本で説明されている。 –

+0

http://stackoverflow.com/help/how-to-answer – peetonn

7

ヘッダーファイル間に循環依存関係があります。あなたが本当にすることはありませんAおよびB(のための別のヘッダファイルを使用して主張する場合

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

class B 
{ 
    ... 
}; 

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

:あなたのクラスは非常に緊密に絡み合っているので、私はこのような構造の単一のヘッダーファイル、にそれらをマージすることをお勧めしたいですそれらが互いに結びついてからの相違)、ヘッダーの1つに他のヘッダーが含まれないように再構成する必要があるため、依存するテンプレート関数の少なくとも1つを別々のファイルで定義する必要があります。たとえば:循環依存関係があるので

// 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 
} 
+0

ありがとう、それはうまく動作します。クラス宣言の前に両方ともディレクティブを含めるようにしました... – Ian

4

、あなたはメンバ関数が定義される前に、彼らは両方とも宣言されているように、慎重にクラス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最初のいずれかを含むなくすることができるようになります。

+0

ありがとう、それはうまくいきます。クラス宣言の前に両方ともディレクティブを含めるようにしました... – Ian

関連する問題