2011-10-25 31 views
15

này đôi chút mã gây nên sự tức giận của mối liên kết khi đưa vào ít nhất hai đơn vị dịch (file cpp):Tại sao trình liên kết phàn nàn về nhiều định nghĩa trong mẫu này?

# ifndef MAXIMUM_HPP 
# define MAXIMUM_HPP 

template<typename T> 
T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

/* dumb specialization */ 
template<> 
int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 

# endif // MAXIMUM_HPP 

Nhưng biên dịch và liên kết tốt với một đơn vị dịch thuật. Nếu tôi loại bỏ chuyên môn, nó hoạt động tốt trong mọi tình huống. Đây là thông điệp của liên kết:

g++ -o test.exe Sources\test.o Sources\other_test.o 
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)' 
Sources\test.o:test.cpp:(.text+0x14): first defined here 

Các mẫu không được phép được khởi tạo nhiều lần? Làm thế nào để giải thích lỗi này và cách khắc phục?

Cảm ơn lời khuyên nào!

+0

Bạn có lẽ nên trả về một tài liệu tham khảo từ các chức năng của mình. – Dani

+0

Nó chỉ là một ví dụ kết quả từ việc theo dõi các lỗi tôi gặp phải trong một mã phức tạp hơn. Tôi nghĩ rằng ví dụ có thể rõ ràng hơn mà không có bất kỳ tham chiếu nào cả :) – overcoder

Trả lời

30

Chuyên môn vì mẫu hoàn toàn rõ ràng phải được xác định chỉ một lần - Trong khi trình liên kết cho phép xác định chuyên môn ẩn nhiều lần, nó sẽ không cho phép chuyên môn rõ ràng, nó chỉ coi chúng như một hàm bình thường.
Để khắc phục lỗi này, đặt tất cả các chuyên ngành trong file nguồn như:

// header 

// must be in header file because the compiler needs to specialize it in 
// different translation units 
template<typename T> 
T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

// must be in header file to make sure the compiler doesn't make an implicit 
// specialization 
template<> int maximum(const int & a, const int & b); 

// source 

// must be in source file so the linker won't see it twice 
template<> 
int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 
+0

Tôi cảm thấy biết ơn hơn! Tôi vừa mới hỏi bạn cách viết lại tập tin tiêu đề! – overcoder

11

Khai báo các chức năng inline

// must be in header file because the compiler needs to specialize it in 
// different translation units 
template<typename T> 
inline T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

/* dumb specialization */ 
template<> 
inline int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 
+1

Rất cám ơn! Tôi nghĩ chúng ta có thể có được một câu trả lời hoàn chỉnh và chính xác nếu chúng ta có thể hợp nhất câu trả lời của bạn với câu trả lời của Dani. – overcoder

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