Tôi có một lớp mẫu mà tôi khai báo trong tiêu đề với một phương pháp và không định nghĩa phương thức đó trong tiêu đề. Trong tệp .cc, tôi xác định chuyên môn của phương thức đó mà không bao giờ khai báo chúng trong tiêu đề. Trong một tệp .cc khác, tôi gọi phương thức cho các tham số mẫu khác nhau mà các chuyên môn tồn tại. Nó trông giống như thế này:Chuyên môn thành viên của lớp mẫu mà không cần khai báo trong tiêu đề
foo.h:
template<typename T>
class Foo {
public:
static int bar();
};
foo.cc:
#include "foo.h"
template<>
int Foo<int>::bar() {
return 1;
}
template<>
int Foo<double>::bar() {
return 2;
}
main.cc:
#include <iostream>
#include "foo.h"
int main(int argc, char **argv) {
std::cout << Foo<int>::bar() << std::endl;
std::cout << Foo<double>::bar() << std::endl;
return 0;
}
Chương trình này biên dịch và liên kết thành công với gcc 4.7.2 cho tất cả các tiêu chuẩn C++ (C++ 98, gnu ++ 98, C++ 11 và gnu ++ 11). Đầu ra là:
1
2
Điều này có ý nghĩa với tôi. Do đơn vị dịch main.cc không thấy định nghĩa là bar()
hoặc bất kỳ chuyên môn nào của nó, nó mong đợi các cuộc gọi đến bar()
để sử dụng các cảnh báo rõ ràng của định nghĩa không được chỉ định của bar()
trong một số đơn vị dịch khác. Nhưng kể từ khi mang tên có thể dự đoán được, các chuyên ngành trong foo.cc có cùng tên biểu tượng như là các instantiation rõ ràng của một định nghĩa không chuyên biệt, do đó, main.cc có thể sử dụng các chuyên ngành đó mà không cần chúng được khai báo trong đơn vị dịch đó.
Câu hỏi của tôi là: đây có phải là tai nạn hay hành vi này được bắt buộc theo tiêu chuẩn C++? Nói cách khác, mã này có phải là di động không?
Câu hỏi trước có liên quan nhất mà tôi có thể tìm thấy là Declaration of template class member specialization, nhưng không bao gồm trường hợp cụ thể này.
(Trong trường hợp bạn tự hỏi tại sao điều này lại quan trọng với tôi, đó là vì tôi đang sử dụng mã như thế này như một bảng tra cứu thời gian biên dịch và ngắn hơn rất nhiều nếu tôi không khai báo chuyên môn .)
Đây là câu hỏi đầu tiên khá tốt! Tôi nghĩ rằng trình biên dịch của IBM cho phép bạn khai báo các chuyên môn của bạn bằng cách sử dụng từ khóa extern, nhưng không bao giờ tự mình thực hiện nó. –