2012-01-03 39 views
7

Các mã sau đây:C++: đặc tả từng phần của các lớp mẫu template

using namespace std; 

template <typename X> 
class Goo {}; 


template <typename X> 
class Hoo {}; 


template <class A, template <typename> class B = Goo > 
struct Foo { 
    B<A> data; 
    void foo1(); 
    void foo2(); 

}; 


template <typename A> 
void Foo<A>::foo1() { cout << "foo1 for Goo" << endl;} 


int main() { 
    Foo<int> a; 
    a.foo1(); 

} 

mang lại cho tôi một lỗi biên dịch:

test.cc:18: error: invalid use of incomplete type 'struct Foo<A, Goo>' 
test.cc:11: error: declaration of 'struct Foo<A, Goo>' 

Tại sao tôi không thể một phần chuyên foo1()? Nếu đây không phải là cách, làm thế nào để làm điều này?

Tôi có một câu hỏi khác: nếu tôi muốn foo2() chỉ được xác định cho A = int, B = Hoo và không cho bất kỳ kết hợp nào khác, làm cách nào để làm điều đó?

+1

Đây không phải là một chuyên môn hóa một phần, Foo có hai tham số và bạn chỉ định một trong 'Foo :: foo1'. –

+0

Và X là gì trong Goo . Goo là mẫu lấy tham số X. Nó được chỉ định ở đâu? – jmucchiello

Trả lời

4

Mẫu chức năng chỉ có thể là đầy đủ chuyên biệt, không phải một phần.

hàm thành viên của lớp mẫu sẽ được tự động hoạt động mẫu, và họ thực sự có thể được chuyên, nhưng chỉ đầy đủ:

template <> 
void Foo<int, Goo>::foo1() { } // OK 

Bạn một phần có thể chuyên toàn bộ lớp và sau đó xác định nó một lần nữa:

template <typename A> 
struct Foo<A, Goo> 
{ 
    // ... 
}; 

(Xem 14.7.3 để biết chi tiết.)

+0

Tôi không nghĩ rằng anh ấy thậm chí còn cố gắng chuyên môn hóa. Chỉnh sửa: Ah phải, bởi "chuyên môn hóa một phần" anh ta muốn bỏ qua một trong các tham số. – someguy

+0

Vì vậy, không có cách nào để chuyên về một phần phương pháp thành viên của một lớp mẫu, mà không chuyên toàn bộ lớp đó? – user231536

+0

@ user231536: Không, thực sự. Đây là [câu trả lời tương tự, trước đây] (http://stackoverflow.com/a/7517290/596781). –

1

Mẫu vẫn có hai tham số và bạn ust viết một cái gì đó như thế này:

template <typename A, template <typename> class B> 
void Foo<A,B>::foo1() { cout << "foo1" << endl;} 

Giá trị mặc định đã được chỉ định và chỉ cần được chỉ định một lần. Từ đó trở đi, nó giống như bất kỳ mẫu hai tham số nào khác. Mã này sẽ áp dụng cho dù B là gì (mặc định hoặc ngược lại). Nếu sau đó bạn muốn chỉ định hành vi khác nhau cho một B, cụ thể thì bạn chuyên môn hóa lớp học, không chỉ là một phương pháp.

(nặng nề sửa)

+0

Tôi nghĩ rằng một số kết hợp của câu trả lời @ KerreckSB, và có lẽ của tôi, có thể là chính xác. Tôi không chắc mục tiêu cuối cùng là gì. Cuối cùng, tôi nghĩ rằng một 'foo1()' hoàn toàn không chuyên biệt sẽ cần được thực hiện sớm hay muộn, giống như cái tôi đã viết. –

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