2010-12-31 34 views
19

Có 2 lớp không phải mẫu A, B có một số phương pháp mẫu tĩnh.Lỗi: loại không đầy đủ được sử dụng trong thông số tên lồng nhau

Từ lớp A phương pháp tĩnh trong B được gọi và từ lớp B phương pháp tĩnh từ A được gọi. Mã nguồn chỉ mang tính minh họa (mã không thực) ...

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

Tôi gặp rắc rối với g ++ biên dịch trong NetBeans. Trong quá trình biên dịch, lỗi sau xảy ra: Lỗi: loại không hoàn chỉnh A được sử dụng trong trình chỉ định tên lồng nhau, g ++.

Tôi đã cố gắng thêm các khai báo chuyển tiếp vào cả hai lớp, nhưng không có gì thành công.

Có một lỗi cũ:

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

Trả lời

0

Vấn đề của bạn là phụ thuộc phần đầu tròn.

+29

Và giải pháp là ...? –

+1

Những người downvoting cần phải nêu rõ những gì họ phản đối. Vì đó là câu trả lời đúng cho câu hỏi OP. OP không yêu cầu giải thích làm thế nào để giải quyết các phụ thuộc tiêu đề tròn, những tầm thường này được giải thích trong mỗi cuốn sách. –

+0

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

7

Bạn có phụ thuộc vòng tròn giữa các tệp tiêu đề của mình. Kể từ khi lớp học của bạn được hòa quyện vào nhau thật chặt, tôi muốn đề nghị sáp nhập chúng vào một tập tin tiêu đề duy nhất, có cấu trúc như thế này:

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

class B 
{ 
    ... 
}; 

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

Nếu bạn nhấn mạnh vào việc sử dụng tập tin tiêu đề riêng biệt cho A và B (mà sẽ không thực sự làm bất kỳ sự khác biệt nào kể từ khi chúng kết thúc với nhau), bạn sẽ cần phải cấu trúc lại chúng để một trong các tiêu đề không bao gồm các tiêu đề khác, vì vậy ít nhất một trong các hàm mẫu phụ thuộc sẽ cần phải được định nghĩa trong một tệp riêng biệt. Ví dụ:

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

Cảm ơn, nó hoạt động tốt. Tôi đã có cả hai chỉ thị trước khi khai báo lớp học ... – Ian

4

Bởi vì có một phụ thuộc vòng tròn, bạn cần phải sắp xếp một cách cẩn thận tờ khai của các tầng lớp AB để họ đều khai báo trước khi các hàm thành viên được định nghĩa.

Đây là 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 

Đây là 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 

Với phương pháp này, bạn sẽ có thể bao gồm một trong hai A.h hoặc B.h đầu tiên và không có một vấn đề.

+0

Cảm ơn, nó hoạt động tốt. Tôi đã có cả hai chỉ thị trước khi khai báo lớp ... – Ian

Các vấn đề liên quan