2011-02-05 36 views
7

Có một tuyên bố của lớp mẫu với các thông số ngầm:Templates với các thông số ngầm, khai về phía trước, C++

List.h

template <typename Item, const bool attribute = true> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    .... 
}; 

Tôi cố gắng để sử dụng tờ khai chuyển tiếp fllowing trong một tập tin tiêu đề khác nhau :

Analysis.h

template <typename T, const bool attribute = true> 
class List; 

Nhưng G ++ cho thấy lỗi này:

List.h:28: error: redefinition of default argument for `bool attribute' 
Analysis.h:43: error: original definition appeared here 

Nếu tôi sử dụng tờ khai phía trước không có tham số ngầm

template <typename T, const bool attribute> 
class List; 

trình biên dịch không chấp nhận xây dựng này

Analysis.h

void function (List <Object> *list) 
{ 
} 

và hiển thị lỗi sau (ví dụ: không chấp nhận những giá trị tiềm ẩn):

Analysis.h:55: error: wrong number of template arguments (1, should be 2) 
Analysis.h:44: error: provided for `template<class T, bool destructable> struct List' 
Analysis.h:55: error: ISO C++ forbids declaration of `list' with no type 

câu hỏi Cập nhật:

tôi loại bỏ các thông số mặc định từ mẫu định nghĩa:

List.h

template <typename Item, const bool attribute> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    .... 
}; 

Đầu tiên tệp bằng cách sử dụng danh sách lớp có khai báo chuyển tiếp với giá trị ngầm của thuộc tính tham số

Analysis1.h

template <typename T, const bool attribute = true> 
class List; //OK 

class Analysis1 
{ 
    void function(List <Object> *list); //OK 
}; 

Lớp thứ hai sử dụng Danh sách lớp VỚI định nghĩa về phía trước bằng cách sử dụng giá trị tiềm ẩn

Analysis2.h

template <typename T, const bool attribute = true> // Redefinition of default argument for `bool attribute' 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //OK 
}; 

Lớp thứ hai sử dụng Danh sách lớp KHÔNG nét về phía trước sử dụng giá trị tiềm ẩn

Phân tích2.h

template <typename T, const bool attribute> // OK 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //Wrong number of template arguments (1, should be 2) 
}; 
+0

Được rồi tôi hiểu vấn đề của bạn. Đó là bởi vì bạn thêm khai báo chuyển tiếp vào mỗi tệp nơi bạn * sử dụng * 'Danh sách'. DONT DO RATNG. Thay vào đó, hãy thêm khai báo chuyển tiếp vào trong 'List.h' trong đó bạn * định nghĩa *' List' ** và ** '#include" List.h "' trong mọi tệp nơi bạn sử dụng 'List'. Hãy cho tôi biết nếu bạn vẫn gặp vấn đề! – Nawaz

+0

vì vậy câu hỏi của bạn sau khi cập nhật là gì? – UmmaGumma

Trả lời

5

Đơn giản.Loại bỏ giá trị mặc định khỏi định nghĩa, vì bạn đã đề cập đến nó trong khai báo chuyển tiếp.

template <typename Item, const bool attribute = true> //<--- remove this 'true` 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

Viết:

template <typename Item, const bool attribute> //<--- this is correct! 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

Demo Online: http://www.ideone.com/oj0jK

+1

Cảm ơn, nó hoạt động :-). – Robo

+0

@Robo: Nếu nó hoạt động, sau đó "chấp nhận" câu trả lời này bằng cách nhấp vào dấu tick. Cho đến nay bạn đã không chấp nhận ngay cả một câu trả lời duy nhất! – Nawaz

+0

@Nawaz: Tôi muốn đặt giá trị mặc định vào khai báo thay vì khai báo chuyển tiếp. Tôi nghĩ nó còn rõ ràng hơn theo cách này. – jopasserat

0

bạn có thể xác định tham số mặc định chỉ ở một nơi (đối với bản dịch đã cho). nó là hữu ích nhất để làm như vậy tại tuyên bố lớp học, và một ý tưởng tồi để xác định nó ở phía trước.

chuyển tiếp không cần tham số mặc định (bạn chỉ cần nhập thông số này trong một số trường hợp).

bạn có thể tạo một loại mẫu đơn giản khác, thực hiện điều này cùng với tiến trình, nếu bạn thực sự muốn tham số mặc định. sau đó bạn truy cập kết quả thông qua typedef. bạn có thể làm điều này bằng cách sử dụng chuyển tiếp Danh sách.

0

Bạn phải chắc chắn rằng chỉ việc khai báo đầu tiên có giá trị mặc định của tham số. Điều này có thể được thực hiện bằng cách đầu tiên xác định tiêu đề chỉ khai báo chuyển tiếp, sau đó bao gồm tiêu đề từ cả hai số List.hAnalysis.h. Trong định nghĩa trong List.h, không bao gồm giá trị mặc định.

0

Bạn phải bao gồm List.h trong mọi tệp, nơi bạn đang sử dụng. Tuyên bố là đủ chỉ cho các loại nontemplate. Đối với các loại mẫu, bạn phải bao gồm tệp tiêu đề cho mọi đơn vị biên dịch.

+0

Nhưng làm thế nào để tránh các dấu ngoặc tròn trong các tập tin tiêu đề bằng cách sử dụng mô hình này? – Robo

+0

@Robo Tôi không nói, rằng bạn không thể tuyên bố nó, tôi nói, rằng bạn phải bao gồm tập tin tiêu đề. Để giải quyết các phụ thuộc bạn có thể xảy ra phải khai báo các lớp trước khi đưa vào tiêu đề. Nhưng bạn ăn cắp cần phải bao gồm tiêu đề – UmmaGumma

+0

Cảm ơn câu trả lời của bạn, tôi đã cập nhật câu hỏi của mình ... – Robo

2

Một giải pháp khả thi là để tuyên bố một tập tin tiêu đề khác, List_fwd.h

template <typename Item, const bool attribute> 
class List; 

Vì vậy, trong cả hai List.h và Analysis.h bạn bao gồm List_fwd.h lúc đầu. Vì vậy, List.h trở thành

#include "List_fwd.h" 

template <typename Item, const bool attribute = true> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    ... 
}; 

Và Analysis.h

#include "List_fwd.h" 
Các vấn đề liên quan