2009-10-08 44 views
10

Có chuyên môn hóa một phần cho phương thức lớp mẫu không?C++ một phần phương pháp chuyên môn

template <class A, class B> 
class C 
{ 
    void foo(); 
} 

nó không hoạt động chuyên nó như thế này:

template <class A> void C<A, CObject>::foo() {}; 

Bất kỳ sự giúp đỡ?

+0

Có một số cách được hiển thị trên các câu trả lời khác: http://stackoverflow.com/questions/1501357/template-specialization-of-particular-members/1501455#1501455 –

Trả lời

11

Nếu bạn đã có chuyên lớp học mà bạn có thể cung cấp cho thực hiện khác nhau của foo trong lớp học chuyên ngành:

template<typename A, typename B> 
class C 
{ 
public: 
    void foo() { cout << "default" << endl; }; 
}; 

template<typename A> 
class C<A, CObject> 
{ 
public: 
    void foo() { cout << "CObject" << endl; }; 
}; 

Để chuyên hàm thành viên trong Visual C++ 2008, bạn có thể làm cho nó template quá:

template<typename A, typename B> 
class C 
{ 
    template<typename T> 
    void foo(); 

    template<> 
    void foo<CObject>(); 
}; 

Giải pháp trên dường như sẽ chỉ có sẵn trong Tiêu chuẩn C++ trong tương lai (theo dự thảo n2914 14.6.5.3/2).

+0

Trong khi thứ hai là đúng, đầu tiên là sai - bạn không thể đặt chuyên môn rõ ràng trong phạm vi lớp - và thậm chí nếu bạn đặt chuyên môn hóa khuôn mẫu trong phạm vi không gian tên - nếu bạn chuyên mẫu, thì tất cả các mẫu kèm theo của nó phải được chuyên biệt hóa Vì vậy, bạn phải gắn bó với cách thứ hai –

+0

Vì vậy, điều này sẽ không làm việc ví dụ: 'template template <> void C :: foo () {}', bởi vì trong khi mẫu chức năng thành viên là chuyên ngành, bên ngoài là một trong chưa.Bạn có thể làm theo cách khác xung quanh mặc dù 'template <> mẫu void C :: foo() {}' nhưng tôi nghi ngờ đây không phải là những gì anh ta muốn để làm -.- –

+0

Đầu tiên có vẻ không phải là C++ 03 Chuẩn tuân thủ, nhưng nó hoạt động trong Visual C++ 2008. Nó trông giống như C++ 0x mở rộng (14.6.5.3 Thành viên của lớp mẫu specia lizations). –

1

Kể từ khi lớp là mẫu, bạn cần phải chuyên rằng:

template <class A> 
class C<A, CObject> 
{ 
    void foo() { ... } 
} 
+0

Tôi đã lớp học chuyên môn, nhưng tôi chính xác cần phải chuyên phương pháp :) – faya

0

Nếu tôi nhớ không lầm thì bạn không thể làm một phần mẫu chuyên môn cho các chức năng. Không chắc chắn cho dù nó được bao gồm trong C++ 0X

Cập nhật: (Đang chờ xác nhận) Như đã đề cập trong các ý kiến, một phần mẫu chuyên môn hóa các chức năng có thể trong C++ 0X.

+0

Hạn chế này được nâng lên trên C++ 0x –

+0

@yngvedh, bạn có tham chiếu cho ghi chú "Cập nhật:" đó không? Tôi chưa nghe về điều này. Tuy nhiên, chúng chỉ là các đối số mặc định sống động - tức là bạn có thể có đối số mặc định trong các mẫu hàm. –

+0

@ libt, không có tham chiếu. Tôi chỉ giả định the_drow biết những gì ông đã nói về như tôi không có chuyên gia về C + + 0X. Có ai biết điều này không? Tôi sẽ cập nhật một cách thích hợp. –

8

Tôi nghĩ có một sự hiểu lầm ở đó.

Có hai loại mẫu:

  • các lớp mẫu
  • mẫu phương pháp

Trong ví dụ của bạn, bạn có một lớp mẫu, trong đó tất nhiên có chứa một số phương pháp. Trong trường hợp này, bạn sẽ phải chuyên lớp đó.

template <class A> 
class C<A,CObject> 
{ 
    void foo() { ... } // specialized code 
}; 

Vấn đề trong ví dụ của bạn là tương đối đơn giản: bạn xác định phương pháp foo cho chuyên môn hóa C nhưng chuyên môn hóa này chưa bao giờ được công bố trước.

Vấn đề ở đây là bạn phải hoàn toàn chuyên về lớp C của bạn (và do đó sao chép rất nhiều dữ liệu). Có một số cách giải quyết.

  • Thừa kế (Thành phần?): làm tất cả công việc phổ biến trong lớp cơ sở, sau đó có lớp C kế thừa và chuyên môn thích hợp
  • Bạn bè: thay vì có phương pháp 'foo' là thành viên của C, hãy xác định nó là một chức năng miễn phí của người bạn và chuyên chỉ phương pháp này
  • Phái đoàn: có phương pháp 'foo' của bạn gọi một phương pháp 'bar', mà là một chức năng miễn phí, và chuyên 'bar' một cách thích hợp

nào trong mã cho:

// 1- Inheritance 
template <class A, class B> 
class CBase 
{ 
    // Everything that does not require specialization 
}; 

template <class A, class B> 
class C: public CBase<A,B> 
     // depending on your need, consider using another inheritance 
     // or even better, composition 
{ 
    void foo(); // generic 
}; 

template <class A> 
class C<A,CObject> : public CBase<A,CObject> 
{ 
    void foo(); // specialized 
}; 

// 2- Friend 
// note the change in signature: 
// - now you need to pass the attributes to be changed 
// - the last parameter helps differentiating the overload 
// as there is no specialization for functions 
template <class A, class B> void foo(Arg1&, Arg2&, const B&); 
template <class A> void foo(Arg1&, Arg2&, const CObject&); 

template <class A, class B> 
class C 
{ 
    friend template <class, class> foo; 
}; 

// 3- Delegation 
// same signature as foo in (2) 
template <class A, class B> void bar(Arg1&, Arg2&, const B&); 
template <class A> void bar(Arg1&, Arg2&, const CObject&); 

template <class A, class B> 
class C 
{ 
    void foo() { bar(member1, member2, B()); } 
}; 

Hy vọng nó làm rõ, và giúp!

2

Không, không có chuyên môn mẫu chức năng từng phần trong C++ 0x được thêm vào.

Như đã đề cập một cách chính xác trên, liên quan đến chức năng cơ bản mẫu thứ 2 đã được thực hiện:

  • luận mẫu mặc định đã được thực hiện có sẵn;
  • Các mẫu biến thể đã được giới thiệu.

Vì vậy, trước đây, cách giải quyết nên được sử dụng để "mô phỏng" chuyên môn hóa một phần mẫu chức năng.

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