Đôi khi khi mã hóa với các mẫu C++, bạn muốn ngăn người dùng khởi tạo chuyên môn cụ thể hoặc tập hợp chuyên môn, vì kết quả sẽ không vô nghĩa. Vì vậy, bạn có thể định nghĩa một chuyên môn (cụ thể hoặc một phần) có định nghĩa, nếu được khởi tạo, sẽ gây ra lỗi trình biên dịch. Mục tiêu sẽ là, nếu người dùng "lạm dụng" mẫu, gây ra lỗi trình biên dịch ngay bên cạnh nhận xét trong tệp tiêu đề của bạn giải thích những gì không làm, thay vì để trình biên dịch đưa ra một thông báo lỗi khó hiểu thiết bị hoặc có thể cho phép mã có vấn đề để biên dịch.Làm thế nào để cố ý gây ra lỗi biên dịch trên bản mẫu instantation
Ví dụ:
template <typename T> struct MyClassTemplate {
// ...
};
template <typename T> struct MyClassTemplate<T*> {
// Do not use MyClassTemplate with a pointer type!
typedef typename T::intentional_error err;
};
Có một số cách để làm điều này (tùy thuộc vào việc chuyên môn của bạn là một chuyên môn hóa hoàn toàn hoặc một phần của một lớp hoặc chức năng). Nhưng cú pháp được sử dụng phải (?) Phụ thuộc vào tham số mẫu, hoặc trình biên dịch khác sẽ khiếu nại khi nó phân tích cú pháp định nghĩa lỗi cố ý đầu tiên. Ví dụ trên có một lỗ hổng trong đó ai đó có thể bướng bỉnh xác định một loại lồng nhau hoặc thành viên typedef intentional_error
(mặc dù tôi muốn nói rằng sau đó họ sẽ xứng đáng với bất kỳ vấn đề nào nảy sinh). Nhưng nếu bạn sử dụng một mẹo quá ưa thích, bạn có thể nhận được thông báo lỗi trình biên dịch không thể giải mã và/hoặc gây nhầm lẫn, chủ yếu đánh bại mục đích.
Có cách nào đơn giản hơn để không cho phép instantiation mẫu không?
Tôi biết rằng trong C++ 0x, khái niệm mẫu và khai báo hàm đã xóa sẽ cung cấp khả năng kiểm soát tốt hơn đối với loại điều này, nhưng tôi đang tìm câu trả lời hợp lệ C++ 03.
Một số trong số này sẽ cung cấp lỗi tại thời gian liên kết chứ không phải là thời gian biên dịch phải không? – zwol
@Zack tất cả sẽ cung cấp lỗi tại thời gian biên dịch. –
Ồ, phải, bởi vì để khởi tạo một lớp mẫu một phải có khai báo lớp đầy đủ. Tôi đã suy nghĩ về các mẫu chức năng. – zwol