2012-02-19 44 views
6

Tôi muốn sử dụng các trình vòng lặp trong phương thức lớp mẫu. Đây là mã của tôi: (testclass.h)Các tham chiếu không xác định đối với các hàm thành viên của một mẫu lớp

template<typename T, typename container> 
class TestClassX 
{ 
public: 
    void gen(typename container::iterator first); 
}; 

và tập tin testclass.cpp:

template<typename T, typename container> 
void TestClassX<T, container>::gen(typename container::iterator first) 
{ 

} 

Khi tôi cố gắng để chạy nó:

TestClassX<unsigned, std::vector<unsigned> > testx; 
testx.gen(it); 

tôi nhận được một lỗi:

Error:undefined reference to `TestClassX<unsigned int, std::vector<unsigned int, std::allocator<unsigned int> > >::gen(__gnu_cxx::__normal_iterator<unsigned int*, std::vector<unsigned int, std::allocator<unsigned int> > >)' 

Tôi sử dụng mingw32 4.4

Tôi muốn có một lớp có thể ghi vào các vùng chứa khác nhau như std :: vector, std :: list, QVector hoặc QList tất cả đều có trình lặp kiểu STL.

+0

có thể trùng lặp của [Chưa xác định tham chiếu đến thành viên mẫu] (http://stackoverflow.com/questions/4100893/undefined-reference-to-template-members) – kennytm

Trả lời

10

Phương thức lớp mẫu phải được xác định trong tệp tiêu đề. Khi bạn sử dụng một lớp mẫu, trình biên dịch thực sự biên dịch một phiên bản của lớp đó cho các tham số mẫu đã cho. Vì vậy, nó là một yêu cầu rằng cơ thể của mỗi phương pháp có sẵn khi bao gồm các tập tin tiêu đề.

Remove bạn file nguồn và bao gồm cơ thể trong testclass.h: phương pháp lớp

template<typename T, typename container> 
class TestClassX 
{ 
public: 
    void gen(typename container::iterator first) { 

    } 
}; 
+0

Phương thức lớp mẫu không cần phải được xác định trong tiêu đề tập tin. Bạn chỉ cần để cho liên kết tìm thấy nó. Đồng ý với @Thaddeus –

1

Template không cần phải được xác định trong tập tin tiêu đề. Nhưng nếu bạn làm điều này, bạn cần xác định một đơn vị biên dịch riêng biệt (ví dụ: templates.cpp) và trong đó bạn bao gồm tệp mã nguồn của lớp mẫu (ví dụ: #include "container.cpp" // the .cpp NOT the .hpp tập tin) sau đó bạn cần phải xác định các trường hợp của các mẫu mà bạn đang sử dụng (ví dụ như mẫu lớp Container;). Bạn cũng cần xác định đối tượng cho lớp mẫu (ví dụ Link). Trong trường hợp cụ thể này, vì chúng ta đang sử dụng một con trỏ tới đối tượng này (ví dụ Link *, trong Containter), chúng ta chỉ cần 'forward declare' đối tượng đó.

Đây là tệp template.cpp đầy đủ. Mà bạn sẽ biên dịch và liên kết với phần còn lại của mã.

class Link; 
#include "Container.cpp" // use the source code, not the header 
template class Container<Link*>; 

Tôi thích sử dụng phương pháp này vì nó ngăn trình biên dịch tạo các thể hiện mẫu mẫu một cách tự động và cho bạn biết khi nào nó không thể tìm thấy nó.

Biên dịch bằng gcc bằng cách sử dụng các mẫu tùy chọn-không rõ ràng.

Khi bạn xây dựng mọi thứ sẽ được biên dịch như bình thường nhưng sau đó trình thu thập sẽ biên dịch lại tệp templates.cpp cho tất cả các đối tượng sử dụng mẫu.

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