2010-12-31 12 views
19

Istnieją dwie nie szablonowe klasy A, B mające pewne statyczne metody szablonów.Błąd: niekompletny typ użyty w specyfikatorze nazwy zagnieżdżonej

Z klasy A jest wywoływana metoda statyczna w B, a od klasy B wybrano metodę statyczną z A. Kod źródłowy tylko w celach ilustracyjnych (nie prawdziwy kod) ...

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

Mam kłopoty z kompilator g ++ w NetBeans. Podczas kompilacji występuje następujący błąd: Błąd: niekompletny typ A używany w zagnieżdżonym specyfikatorze nazwy, g ++.

Próbowałem dodać deklaracje przekazania do obu klas, ale nic się nie udało.

Jest starszy bug:

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

Odpowiedz

0

Twój problem jest okrągła zależność nagłówka.

+29

A rozwiązaniem jest ...? –

+1

Ci, którzy rzucają się w cień, muszą powiedzieć, przeciwko czemu sprzeciwiają się. Ponieważ jest to poprawna odpowiedź na pytanie OP. OP nie prosi o wyjaśnienie, w jaki sposób rozwiązywać zależność od okrągłych nagłówków, te trywialności są wyjaśnione w każdej książce. –

+0

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

7

Masz okrężną zależność między plikami nagłówkowymi. Ponieważ twoje zajęcia są tak ściśle ze sobą powiązane, sugeruję łącząc je w jeden plik nagłówka, skonstruowany tak:

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

class B 
{ 
    ... 
}; 

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

Jeśli upierasz się przy użyciu oddzielnych plików nagłówkowych dla A i B (co nie będzie naprawdę jakakolwiek różnica, ponieważ kończą się one nawzajem), musisz je zrestrukturyzować, aby jeden z nagłówków nie zawierał drugiego, więc przynajmniej jedna z zależnych funkcji szablonu będzie musiała zostać zdefiniowana w oddzielnym pliku. Na przykład:

// 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

Dzięki, działa dobrze. Posiadałem obie dyrektywy przed deklaracjami klasy ... – Ian

4

Ponieważ istnieje zależność cykliczna, trzeba starannie zorganizować deklaracje klas A i B tak, że są one zarówno zadeklarowane przed funkcje składowe są zdefiniowane.

Oto 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 

Oto 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 

Dzięki takiemu podejściu, będzie można włączyć albo A.h lub B.h pierwszy i nie ma problemu.

+0

Dzięki, działa dobrze. Przed deklaracjami klas miałem obie dyrektywy. – Ian

Powiązane problemy