Tôi chỉ có thể nghĩ đến một vài khác biệt - dưới đây là một số ví dụ không nhất thiết gây hại (tôi nghĩ). Tôi đang bỏ qua các định nghĩa để giữ cho nó ngắn gọn
template <typename T> T inc(const T& t);
namespace G { using ::inc; }
template <> int inc(const int& t);
namespace G { void f() { G::inc(10); } } // uses explicit specialization
// --- against ---
template <typename T> T inc(const T& t);
namespace G { using ::inc; }
int inc(const int& t);
namespace G { void f() { G::inc(10); } } // uses template
Đó là vì không tìm thấy chuyên môn bằng tra cứu tên, do đó việc khai báo sử dụng sẽ tự động xem xét chuyên môn sau được giới thiệu.
Sau đó, tất nhiên, bạn không thể chuyên môn hóa một phần mẫu chức năng.Quá tải tuy nhiên hoàn thành một cái gì đó rất giống nhau bởi đặt hàng từng phần (sử dụng các loại khác nhau bây giờ, để làm cho quan điểm của tôi)
template <typename T> void f(T t); // called for non-pointers
template <typename T> void f(T *t); // called for pointers.
int a;
void e() {
f(a); // calls the non-pointer version
f(&a); // calls the pointer version
}
Điều đó sẽ không thể thực hiện với chuyên môn hóa rõ ràng chức năng template. Một ví dụ khác là khi tài liệu tham khảo có liên quan, trong đó nguyên nhân khấu trừ mẫu tranh luận để tìm kiếm một kết hợp chính xác của các loại liên quan (cơ sở modulo/nguồn gốc các mối quan hệ giai cấp và constness):
template<typename T> void f(T const &);
template<> void f(int * const &);
template<typename T> void g(T const &);
void g(int * const &);
int a[5];
void e() {
// calls the primary template, not the explicit specialization
// because `T` is `int[5]`, not `int *`
f(a);
// calls the function, not the template, because the function is an
// exact match too (pointer conversion isn't costly enough), and it's
// preferred.
g(a);
}
tôi khuyên bạn nên luôn luôn sử dụng quá tải, bởi vì nó phong phú hơn (cho phép một cái gì đó như chuyên môn hóa một phần sẽ cho phép), và ngoài ra bạn có thể đặt chức năng trong bất kỳ không gian tên bạn muốn (mặc dù sau đó nó không quá tải nghiêm trọng nữa). Ví dụ, thay vì phải chuyên std::swap
trong không gian tên std::
, bạn có thể đặt quá tải swap
trong không gian tên của riêng bạn và làm cho nó có thể gọi bằng ADL.
Bất kể bạn làm gì, không bao giờ kết hợp chuyên môn và quá tải, nó sẽ là một đống lộn xộn như this article chỉ ra. Tiêu chuẩn có một đoạn văn đáng yêu về nó
Vị trí khai báo chuyên môn rõ ràng cho mẫu chức năng, thành phần dữ liệu tĩnh của mẫu lớp, lớp thành viên của mẫu lớp, mẫu lớp thành viên của các mẫu lớp, các hàm thành viên của các mẫu lớp, các hàm thành viên của các mẫu thành viên của các mẫu lớp, các hàm thành viên của các mẫu thành viên của các lớp không mẫu, các mẫu hàm thành viên của các lớp thành viên của các mẫu lớp, v.v. của các mẫu lớp, các mẫu lớp thành viên của các lớp không phải mẫu, các mẫu lớp thành viên của các mẫu lớp, v.v., có thể ảnh hưởng đến việc một chương trình có được định dạng tốt hay không. arations và điểm của họ về instantiation trong đơn vị dịch thuật như quy định ở trên và dưới đây. Khi viết chuyên môn, hãy cẩn thận về vị trí của nó; hoặc để làm cho nó biên dịch sẽ là một thử nghiệm như để kindle tự thiêu của nó.
Tôi đã bỏ phiếu tán thành câu hỏi vì đây là một trong những vùng tối trong C++ (ít nhất là đối với tôi)! – AraK
Bạn đặc biệt yêu cầu điều gì? Chỉ cần một số khác biệt, hoặc một số trường hợp nguy hiểm được đặt ra? Ví dụ, chắc chắn 'inc <> (10);' ứng xử khác nhau cho hai đoạn trích này - nhưng đó là những gì bạn muốn nghe? –