12

Tôi muốn có hàm mẫu variadic bên trong một lớp. Các đối số mẫu variadic là các ký tự cần được xử lý theo cách giống như vòng lặp. Vì vậy, tôi nghĩ đến việc viết nó giống như trong haskell với head/tail tách danh sách cho đến khi một trường hợp cơ bản (danh sách trống) đạt được.Chức năng mẫu biến thể: chuyên đầu/đuôi và vỏ cơ sở trống

Ví dụ, hãy đếm số lượng đối số đã cho (chỉ một ví dụ tối thiểu).

tôi đã đưa ra đoạn mã sau:

struct MyClass { 
    template<char ...X> 
    static int count(); 
}; 


template<> 
int MyClass::count<>() { 
    return 0; 
} 
template<char Head, char ...Tail> 
int MyClass::count<Head, Tail...>() { 
    return 1 + count<Tail...>(); 
} 

Tuy nhiên, đây doesn't seem to work:

prog.cpp:12:35: error: function template partial specialization ‘count<Head, Tail ...>’ is not allowed 
prog.cpp:12:5: error: prototype for ‘int MyClass::count()’ does not match any in class ‘MyClass’ 
prog.cpp:3:16: error: candidate is: template<char ...X> static int MyClass::count() 

Làm thế nào tôi có thể đạt được điều này? Tôi biết rằng chuyên môn từng phần không được hỗ trợ cho các chức năng. Nhưng tôi nghĩ rằng chuyên một mẫu variadic vào đầu/đuôi và phiên bản trường hợp cơ sở trống không phải là một chuyên môn một phần nhưng chuyên môn đầy đủ, nhưng có thể tôi sai? Tôi có cần phải viết nó như là một lớp thay vì một hàm không?

Tôi đã tìm thấy các ví dụ (printf) thực hiện trường hợp cơ bản mà không cần sử dụng cú pháp mẫu. Nhưng tôi đoán rằng trường hợp của tôi khác, vì lệnh gọi printf không sử dụng cú pháp mẫu nhưng khấu trừ loại, do đó, printf(tail...) gọi printf() nếu tail trống. Mặt khác, trong trường hợp của tôi, khi gọi trường hợp cơ sở, count<>() không giống như count().

+0

Đối với trường hợp đề cập, bạn chỉ có thể tạo ra một tuple từ var arg, và việc sử dụng tuplesize. Có thể tuples dễ dàng hơn để làm việc với, với bất cứ điều gì khác bạn có trong tâm trí? – Skeen

+0

@ Skeen Đây chỉ là một ví dụ rất tối giản mà tại đó vấn đề cơ bản có thể dễ dàng được thảo luận. Tất nhiên, tôi cần một cái gì đó phức tạp hơn. AFAIK, tuple chỉ hoạt động với các loại, không phải với các giá trị. – leemes

+1

Tuples cũng có thể lưu trữ dữ liệu và chúng dường như dễ dàng hơn nếu bạn hỏi tôi. – Skeen

Trả lời

17

tôi sẽ nói đó là thường là một ý tưởng tốt hơn để quá tải chức năng mẫu chứ không phải là chuyên họ:

struct MyClass { 
    template<typename... Tail> 
    static int count() { 
     return 0; 
    } 

    template<char Head, char... Tail> 
    static int count() { 
     return 1 + count<Tail...>(); 
    } 
}; 

#include <iostream> 

int main() { 
    std::cout << MyClass::count<'f','o','o'>(); 
} 

Và đây là một live example. Tôi cũng muốn nhắc tới điều được xây dựng trong điều hành sizeof... thể được sử dụng cho mục đích này:

struct MyClass { 
    template<char... Chars> 
    static int count() { 
     return sizeof...(Chars); 
    //   ^^^^^^^^^ 
    } 
}; 
+0

Ôi trời ơi, hoàn toàn quên mất quá tải. Cảm ơn! (tắt chủ đề: LWS> ideone?) – leemes

+0

@leemes: Bạn được chào đón, hy vọng nó sẽ giúp bạn! –

+0

Tất nhiên có sizeof, 'count' chỉ là ví dụ đơn giản nhất mà tôi có thể đưa ra, mà vẫn chứng minh được vấn đề cơ bản. – leemes

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