2012-04-04 31 views
5

Cho một mẫuChuyên mẫu dựa trên dương tính của các đối số

template <int n> 
void f(){...}; 

Tôi biết tôi có thể chuyên nó cho các giá trị cụ thể của n bằng cách thực hiện:

template <> 
void f<2>(){...}; 

Nhưng, có một phương pháp cho phép tôi để chuyên cho tất cả các tích cực n?

tôi nghĩ về cách làm như sau

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

Vì vậy, đối n<0 mã này là không hợp lệ và trình biên dịch sẽ nghỉ mát để định nghĩa trước. Thật không may, tất cả những gì tôi nhận được là lỗi redefinition of 'void f<n>()'.

Lưu ý: Tôi đoán điều này có thể không được tiêu chuẩn hỗ trợ. Tôi hỏi nếu không có một số phương pháp (có thể một số mẫu metaprogramming) để đạt được hiệu ứng này.

Trả lời

13

Một tùy chọn sẽ là sử dụng cấp độ gián tiếp khác. Xác định mẫu phụ có hai đối số - số nbool đại diện cho hay không n là số âm, sau đó chuyên mẫu đó cho khi n là số âm. Sau đó, hãy để chức năng f của bạn khởi tạo mẫu với các đối số phù hợp.

Ví dụ:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

Một lựa chọn khác là sử dụng SFINAE overloadingstd::enable_if lớp mẫu từ C++ 11 (hoặc Boost của tương đương);

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

Mỗi chức năng này sẽ chỉ khả dụng cho độ phân giải quá tải nếu n có dấu hiệu phù hợp, vì vậy phiên bản chính xác sẽ luôn được gọi.

Hy vọng điều này sẽ hữu ích!

+5

Vấn đề về phong cách, nhưng tôi thích đặt 'enable_if' vào kiểu trả về để không có tham số ma thuật treo quanh những thứ khó hiểu (người dùng và loại của hàm). – GManNickG

Các vấn đề liên quan