2011-10-04 42 views
5

Nói rằng tôi có điều này:mẫu chuyên môn với nhiều mẫu thông số

template<typename T, int X> 
class foo 
{ 
public: 
    void set(const T &t); 
}; 

template<typename T, int X> 
void foo::set<T, X>(const T &t) 
{ 
    int s = X; 
    // ...etc 
} 

Tôi có thể chuyên các loại chức năng 'T' nhưng để lại 'X' như một tham số mẫu?

class bar; 

template<int X> 
void foo::set<bar, X>(const bar &t) 
{ 
    int s = X; 
    // ...etc 
} 

Điều này có khả thi không?

+1

'void foo :: set (const T & t)' -> 'void foo :: đặt (const T & t)' –

Trả lời

6

Đây là đáng ngạc nhiên dễ dàng một khi bạn nhận được hang của nó

template<typename T, int X> 
class foo 
{ 
private: 
    template<typename, int> class params { }; 

public: 
    void set(const T &t) { 
    set(t, params<T, X>()); 
    } 

private: 
    template<typename T1, int X1> 
    void set(const T1 &t, params<T1, X1>) { 
    // ... 
    } 

    template<int X1> 
    void set(const bar &t, params<bar, X1>) { 
    // ... 
    } 
}; 

này là cần thiết bởi vì nếu bạn chuyên rõ ràng một thành viên duy nhất, bạn phải cung cấp tất cả các đối số mẫu . Bạn không thể để lại một số.

+0

Điều đó đúng nhưng cá nhân tôi sẽ tránh các thủ thuật như vậy. Nó làm cho mã không đọc được. IMO một phần chuyên môn của lớp hoặc một cái gì đó tương tự tùy thuộc vào tình huống (ví dụ như tạo mẫu lớp cơ sở và một phần chuyên và thực hiện (nhiều?) Chức năng không chuyên ngành trong lớp không có chuyên môn) là quyết định tốt hơn nhiều. –

+0

@Serge chuyên môn từng phần chuyên về cả lớp. Vì vậy, nó không phù hợp nếu anh ta chỉ muốn hành vi đặc biệt cho một chức năng duy nhất. tạo một mẫu cơ bản là nhiều tiếng ồn và sự bất tiện (bạn sẽ không có quyền truy cập vào các thành viên của "foo", ...). Nếu bạn có một giải pháp sạch hơn ở trên, tôi chào đón bạn để đăng nó. –

+0

"chuyên môn từng phần chuyên về cả lớp" - Đúng. "tạo ra một mẫu cơ sở là nhiều tiếng ồn và sự bất tiện" - Thông thường nó không phải là sự bất tiện - nó là một công việc bổ sung nhỏ để làm cho kiến ​​trúc phù hợp. Nếu có nhu cầu chuyên môn thì thường có một số logic đặc biệt về trường hợp này có thể xứng đáng với chuyên môn riêng biệt (cơ sở) lớp. Nếu có rất nhiều đối tượng thành viên chung thì không có vấn đề gì để đặt chúng (được bảo vệ) trong lớp khác làm cơ sở cho cả hai chuyên môn của cha mẹ (và thường có một logic đằng sau điều này). –

2

Không. Điều đó không được phép. Chức năng thành viên classphải hoàn toàn chuyên biệt. Ví dụ, nó phải là,

template<> 
void foo<bar, 5>::set(const bar &t) 
{   //^^^^ 
    int s = 5; 
    // ...etc 
} 
1

Bạn có thể chuyên môn hóa một phần toàn bộ lớp học. Trong trường hợp này, bạn có thể thực hiện các chức năng khác nhau cho hàm set cho mỗi chuyên môn của lớp.

+0

Bạn có thể đưa ra một ví dụ không? – MarkP

+0

@MarkP, Kiểm tra [this] (http://stackoverflow.com/questions/1535816/c-partial-method-specialization/1535845#1535845) câu trả lời. –

3

Bạn có thể xem xét viết lại mã của bạn để làm cho các chức năng thành viên một mẫu riêng:

template <int X> class foo 
{ 
    template <typename T> void set(const T &); 
    // ... 
}; 

Sau đó, bạn có thể cung cấp các chuyên ngành rõ ràng cho mẫu foo<X>::set.

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