Hơn một lần (thậm chí trên SO) Tôi đã nhìn thấy mã như thế này:Các gói thông số bảo vệ đã được kiểm tra có gây ra các chương trình bị hỏng không?
template<typename U, typename... G, typename T = Traits<U>>
struct {
static_assert(sizeof...(G) == 0, "!");
// ...
};
Hoặc này:
template<typename T, typename... G, typename = std::enable_if_t<condition<T>>
void func(T &&t) {
static_assert(sizeof...(G) == 0, "!");
// ....
}
Mục đích là để tránh sử dụng phá vỡ các quy tắc của trò chơi bằng cách làm một cái gì đó như thế này:
template<typename T, typename = std::enable_if_t<std::is_same<T, int>>
void func(T &&t) {
// ....
}
// ...
func<int&, void>(my_int);
Với gói thông số bảo vệ, giá trị mặc định không thể ghi đè.
Mặt khác, việc kiểm tra kích thước tránh ô nhiễm các chuyên môn với các tham số vô dụng.
Dù sao, vì [temp.res/8], ta có:
Chương trình là vô hình thành, không có chẩn đoán cần thiết, nếu:
[...]
- mỗi chuyên môn hóa có giá trị của một mẫu variadic yêu cầu một mẫu gói tham số rỗng, hoặc
[...]
Do đó, là những chương trình có chứa các đoạn nêu trên vô hình thành hay không?
Có. Đó là lý do tại sao TMP'lers có kinh nghiệm sẽ sử dụng một mẫu lớp có cả kích thước của gói và 'T' để xác định điều kiện' static_assert'. (Mặc dù tôi không biết liệu TMP'lers có kinh nghiệm thực sự sẽ đi với cách tiếp cận này ngay từ đầu.) – Columbo
Tôi không thấy điểm trong việc sử dụng gói tham số ở nơi đầu tiên, bạn chỉ có thể sử dụng 'template, int> = 0> 'không thể được người dùng phá vỡ và cũng có thể được sử dụng trong SFINAE đang bật. –
Corristo
@Corristo, không bao giờ có vẻ như mã như vậy. Bí quyết đẹp! – paulotorrens