2011-07-08 46 views
15

Tôi đang phát xung quanh với chuyên môn về mẫu và tôi đã tìm thấy một vấn đề mà tôi dường như không thể giải quyết; đây là mã của tôi:Chuyên môn về mẫu C++ về các chức năng

template<int length, typename T> 
void test(T* array) 
{ 
    ... 
    test<length-1>(array); 
} 

template<typename T> 
void test<0>(T* array) 
{ 
    return; 
} 

Vì vậy, những gì tôi đang cố gắng làm là vượt qua độ dài, những gì sẽ được xử lý trong mẫu.

Vấn đề là, rằng việc biên soạn này, cũng quả đầu ra mãi mãi:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template 
a.cpp: In function 'void test(T*) [with int length= -0x000000081, T = int]': 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000080, T = int]' 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x00000007f, T = int]' 
a.cpp:77:9: [ skipping 151 instantiation contexts ] 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= 28, T = int]' 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= 29, T = int]' 
... 
a.cpp: In function 'void test(T*) [with int length= -0x000000082, T = int]': 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000081, T = int]' 
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000080, T = int]' 

cuối hai dòng, là khá nhiều giống như những người đầu tiên.

Đối với tôi nó sẽ có vẻ, nó không thu hút sự chuyên môn hóa, do đó:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template 

Tôi thích hợp?

Và nếu tôi đúng, tôi đoán đó là vấn đề chuyên môn hóa một phần mẫu không được phép cho các mẫu chức năng, vậy thì giải pháp sau đó là gì, tạo cấu trúc và sử dụng chuyên môn về điều đó?

Trả lời

15

Không được phép chuyên môn hóa một phần mẫu chức năng. Herb Sutter giải thích lý do tại sao trong bài viết của mình "Why Not Specialize Function Templates?".

Để giải quyết giới hạn này, bạn cần sử dụng mẫu lớp thay thế. Sau đó, bạn có thể viết mẫu chức năng thông thường sử dụng mẫu lớp đó.

Lỗi cụ thể mà bạn nhận được là do bạn đã quên tham số thứ hai trong chuyên môn của mình. Nếu bạn điều này thay vì:

template<int length, typename T> 
void test(T* array) 
{ 
    //... 
    test<length-1,T>(array); 
} 


template<typename T> 
void test<0,T>(T* array) 
{ 
    return; 
} 

GCC complains như sau:

error: function template partial specialization 'test<0, T>' is not allowed

+0

Vì vậy, giải pháp của tôi là gì, sử dụng cấu trúc và tạo chức năng trình bao bọc? – Skeen

+2

Và tại sao nó không được phép? - chỉ tò mò thôi. – Skeen

3

phần chuyên môn của chức năng mẫu is not allowed.

Để giải quyết vấn đề đó, bạn có thể tạo test thành viên tĩnh của mẫu lớp và một phần chuyên về lớp.

7

Chức năng không thể là một phần chuyên biệt. Để giải quyết vấn đề này, hãy để chức năng mẫu của bạn gọi hàm trong một lớp:

template<int length, typename T> 
struct helper 
{ 
    static void go(T* array) 
    { 
     ... 
     helper<length-1, T>::go(array); 
    } 
}; 

template<typename T> 
struct helper<0, T> 
{ 
    static void go(T* array) 
    { 
     ... 
    } 
}; 

template<int length, typename T> 
void test(T* array) 
{ 
    ... 
    helper<length, T>::go(array); 
} 
2

Bạn có thể giải quyết với lớp trợ giúp. Vì mục đích minh họa:

template<typename T, typename U> struct helper_t { 
    static int foo() { return 0; } 
}; 

template<typename T> struct helper_t<T,T> { 
    static int foo() { return 1; } 
}; 

template <typename T, typename U> 
int frob() { 
    return helper_t<T,U>::foo(); 
} 
Các vấn đề liên quan