2010-10-16 32 views
6

Nói rằng tôi có lớp sau:Làm cách nào để chuyên một thành viên tĩnh của một lớp mẫu trên một loại templated?

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 

tôi có thể chuyên A::value trên một loại bê tông không có vấn đề:

struct B 
{ 
}; 

template<> 
int A<B>::value = 1; 

Tôi muốn chuyên A :: giá trị trên một kiểu mẫu, tôi đã thử những điều sau:

template<class T> 
struct C 
{ 
}; 

// error: template definition of non-template 'int A<C<T> >::value' 
template<> 
template<class T> 
int A<C<T> >::value = 2; 

Có cách nào để thực hiện việc này hay chỉ có thể chuyên A :: giá trị trên các loại không phải mẫu?

Trả lời

7

Thay vì giới thiệu một chuyên môn hóa rõ ràng toàn bộ, bạn chỉ có thể chuyên về khởi

template<class T> 
struct Value { 
    static int const value = 0; 
}; 

template<class T> 
struct Value< C<T> > { 
    static int const value = 2; 
}; 

template<class T> 
int A<T>::value = Value<T>::value; 
+0

+1: có thể bạn có nghĩa là Giá trị :: giá trị. – Chubsdad

+0

@Chubsdad là định nghĩa của giá trị OP :: OP. Vaue :: giá trị không cần định nghĩa. –

2

Bạn có thể sử dụng đặc tả từng phần của A qua C:

#include <iostream> 

using namespace std; 

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 

//(1) define the C template class first: 
template<class T> 
struct C 
{ 
}; 

//(2) then define the partial specialization of A, in terms of C: 
template<typename T> 
struct A<C<T> > 
{ 
    static int value; 
}; 

template<typename T> 
int A<C<T> >::value = 2; 

int main(void) 
{ 
    cout<<A<C<int> >::value<<endl; 

    cout<<"ok!"<<endl; 
    return 0; 
} 
+0

Tính năng này hoạt động nhưng không linh hoạt như câu trả lời tôi đã chấp nhận. Tôi dự định mở rộng lớp A cho các kiểu do người dùng định nghĩa khác, và với điều này, tôi cần phải có tất cả các chuyên ngành của A được định nghĩa trước khi sử dụng A, thay vì có thể xác định các giá trị đặc biệt ở bất kỳ đâu và cho phép trình liên kết thực hiện công việc. –

+0

Ok, nếu tôi nhận được điểm chính xác, bạn (hiểu) không thích ràng buộc các chuyên môn của A đối với các định nghĩa mẫu có sẵn và cung cấp một chuyên môn mới mỗi khi bạn xác định một tên mới, như C, được tham số hóa bởi một đối số mẫu. Một giải pháp cho điều đó là sử dụng một phần chuyên môn hóa thông qua một đối số mẫu-template (xem bên dưới câu trả lời thứ 2 của tôi). Hy vọng rằng sẽ giúp. –

0

chuyên môn hóa từng phần qua mẫu-mẫu luận (xem nhận xét của tôi ở trên):

#include <iostream> 

using namespace std; 

template<class T> 
struct A 
{ 
    static int value; 
}; 

template<class T> 
int A<T>::value = 0; 



//solution 2: 
//define a template-template argument partial specialization 
//for any generic class U depending on a template argument, 
//(which is a typename, in this case, but there's no reason why 
//you wouldn't define specializations for non-types, etc.) 
//this specialization has the advantage of not depending on 
//the template definition of U (or C, etc.); in this case 
//both T and U are free to vary, with the only constraint 
//that U is parameterized by T: 
template<typename T, template<typename> class U> 
struct A<U<T> > 
{ 
    static int value; 
}; 

template<typename T, template<typename> class U> 
int A<U<T> >::value = 3; 

//define the C template class, somewhere, where/when/if needed 
//possibly in a different namespace, "module" (etc.) 
template<class T> 
struct C 
{ 
}; 

int main(void) 
{ 
    cout<<A<C<int> >::value<<endl;//this now should print out: 3 

    cout<<"ok!"<<endl; 
    return 0; 
} 
Các vấn đề liên quan