Khi tôi chuyên hàm/hằng số thành viên (tĩnh) trong một lớp mẫu, tôi bị nhầm lẫn là nơi khai báo có nghĩa là để đi.Khai báo chuyên môn thành viên của lớp mẫu
Dưới đây là một ví dụ về những gì tôi phải làm gì - yoinked trực tiếp từ IBM's reference on template specialization:
=== IBM Member Chuyên Ví dụ ===
template<class T> class X {
public:
static T v;
static void f(T);
};
template<class T> T X<T>::v = 0;
template<class T> void X<T>::f(T arg) { v = arg; }
template<> char* X<char*>::v = "Hello";
template<> void X<float>::f(float arg) { v = arg * 2; }
int main() {
X<char*> a, b;
X<float> c;
c.f(10); // X<float>::v now set to 20
}
Câu hỏi đặt ra là, làm thế nào để tôi chia này vào tệp header/cpp? Việc thực hiện chung là rõ ràng trong tiêu đề, nhưng những gì về chuyên môn?
Nó không thể đi trong tập tin tiêu đề, bởi vì nó là cụ thể, dẫn đến nhiều định nghĩa. Nhưng nếu nó đi vào tập tin .cpp, là mã mà gọi X :: f() nhận thức của chuyên môn, hoặc nó có thể dựa vào chung X :: f()?
Cho đến nay tôi chỉ có chuyên môn trong .cpp, không có khai báo trong tiêu đề. Tôi không gặp khó khăn khi biên dịch hoặc thậm chí chạy mã của tôi (trên gcc, không nhớ phiên bản tại thời điểm này), và nó hoạt động như mong đợi - công nhận chuyên môn hóa. Nhưng A) Tôi không chắc điều này là chính xác, và tôi muốn biết cái gì là, và B) tài liệu Doxygen của tôi xuất hiện rất lạc quan và rất gây hiểu lầm (thêm vào đó trong
một thời điểm
câu hỏi sau).
Những gì có vẻ tự nhiên nhất đối với tôi sẽ là một cái gì đó như thế này, tuyên bố chuyên môn hóa trong tiêu đề và xác định nó trong cpp:
=== XClass.hpp ===
#ifndef XCLASS_HPP
#define XCLASS_HPP
template<class T> class X {
public:
static T v;
static void f(T);
};
template<class T> T X<T>::v = 0;
template<class T> void X<T>::f(T arg) { v = arg; }
/* declaration of specialized functions */
template<> char* X<char*>::v;
template<> void X<float>::f(float arg);
#endif
=== XClass.cpp ===
#include <XClass.hpp>
/* concrete implementation of specialized functions */
template<> char* X<char*>::v = "Hello";
template<> void X<float>::f(float arg) { v = arg * 2; }
... nhưng tôi không biết điều này có đúng không. Bất kỳ ý tưởng?
Câu hỏi, trong sự tò mò: tại sao ưu tiên cho nội tuyến? Có vẻ như một "yêu cầu" kỳ lạ để áp đặt - rằng "theo mặc định" một chuyên môn về mẫu sẽ được gạch chân. Tôi hỏi tất cả điều này chỉ vì bạn ngụ ý rằng đó là những gì bạn sẽ "thường" làm, và tôi không thấy lý do tại sao tôi muốn thường làm điều đó nhiều hơn tôi muốn thường tuyên bố bất kỳ nội tuyến chức năng khác. – Ziv
Về sở thích của chúng cho việc đặt chúng vào tiêu đề, 'nội tuyến' là một tác dụng phụ. Ít để viết, cơ hội tối ưu hóa nhiều hơn, không có lỗi bằng cách quên một tuyên bố. Ngoài ra, bạn luôn cần phải hoàn toàn chuyên và đối với hầu hết các mẫu có nghĩa là thêm một khai báo và khởi tạo rõ ràng cho mọi kết hợp các loại được sử dụng. Loại đánh bại ý định của sự hào phóng, phải không? –
Vâng, tất nhiên tôi chỉ nói về các trường hợp khi một chuyên môn đầy đủ là những gì mong muốn, nếu không nó rõ ràng là một câu chuyện hoàn toàn khác ... Lật câu hỏi, sau đó: tại sao những lợi thế đó không khiến chúng ta thích thường viết tất cả các hàm nội tuyến? – Ziv