2010-02-28 42 views
6

Tôi muốn có một lớp mẫu trông giống như những gì tôi có dưới đây. Sau đó, tôi muốn có một chức năng trong đó với một chuyên môn mẫu tùy thuộc vào tham số mẫu CLASS. Làm cách nào để tôi thực hiện công việc này? Tôi nhận ra mã tôi cung cấp là sai ở nhiều cấp độ, nhưng nó chỉ để minh họa cho khái niệm.Lớp mẫu, chuyên môn hóa chức năng

template <typename _T, size_t num> 
class Foo 
{ 
    // If num == 1, I want to call this function... 
    void Func<_T, 1>() 
    { 
     printf("Hi!"); 
    } 

    // Otherwise, I want to call this version. 
    void Func<_T, num>() 
    { 
     printf("Hello world!"); 
    } 
}; 

Trả lời

9
struct Otherwise { }; 
template<size_t> struct C : Otherwise { }; 

// don't use _Uppercase - those names are reserved for the implementation 
// (i removed the '_' char) 
template <typename T, size_t num> 
class Foo 
{ 
public: 
    void Func() { Func(C<num>()); } 

private: 
    // If num == 1, I want to call this function... 
    void Func(C<1>) 
    { 
     printf("Hi 1!"); 
    } 

    // If num == 2, I want to call this function... 
    void Func(C<2>) 
    { 
     printf("Hi 2!"); 
    } 

    // Otherwise, I want to call this version. 
    void Func(Otherwise) 
    { 
     printf("Hello world!"); 
    } 

    //// alternative otherwise solution: 
    // template<size_t I> 
    // void Func(C<I>) { .. } 
}; 
+0

Tôi thích giải pháp này. Tôi thậm chí đã học được điều gì đó về quy ước đặt tên C++! Tuy nhiên, làm thế nào để làm điều này nếu tôi có, nói rằng, bất kỳ số lượng chuyên môn cho các giá trị khác nhau của num cùng với một fall-back trong trường hợp không ai trong số họ làm việc? –

+0

@wowus, câu trả lời cập nhật –

+0

Cảm ơn, đã chấp nhận. –

2

Không có chuyên ngành một phần của chức năng mẫu, và một phần chuyên biệt hoá một thành viên bạn cần phải đầu tiên một phần chuyên các lớp mẫu.

template< typename _T, size_t num > 
struct Foo { 
    void Func() { 
     printf("Hello world!"); 
    } 
}; 

template< typename _T > 
struct Foo< _T, 1 > { 
    void Func() { 
     printf("Hi!"); 
    } 
}; 

Bây giờ, nếu Foo cũng chứa các phương pháp khác hơn Func mà thực hiện không phụ thuộc vào giá trị cho num, và bạn không muốn lặp lại thực hiện của họ trong chuyên môn của Foo, bạn có thể áp dụng mô hình sau:

template< typename _T, size_t num > 
struct FooFuncBase { 
    void Func() { 
     printf("Hello world!"); 
    } 
}; 

template< typename _T > 
struct FooFuncBase< _T, 1 > { 
    void Func() { 
     printf("Hi!"); 
    } 
}; 

template< typename _T, size_t num > 
struct Foo : public FooFuncBase< _T, num > { 
    void OtherFuncWhoseImplementationDoesNotDependOnNum() { 
    ... 
    } 
}; 

Hoặc, sử dụng CRTP:

template< typename _Derived, typename _T, size_t num > 
struct FooFuncBase { 
    void Func() { 
     static_cast< _Derived* >(this)->OtherFuncWhoseImplementationDoesNotDependOnNum(); 
     printf("Hello world!"); 
    } 
}; 

template< typename _Derived, typename _T > 
struct FooFuncBase< _Derived, _T, 1 > { 
    void Func() { 
     static_cast< _Derived* >(this)->OtherFuncWhoseImplementationDoesNotDependOnNum(); 
     printf("Hi!"); 
    } 
}; 

template< typename _T, size_t num > 
struct Foo : public FooFuncBase< Foo< _T, num >, _T, num > { 
    void OtherFuncWhoseImplementationDoesNotDependOnNum() { 
    printf("Other"); 
    } 
}; 
+0

Đó là một lớp học đang được chuyên trong trường hợp này, OP chỉ không biết làm thế nào để viết cú pháp cho rằng tôi nghĩ. –

+1

Tôi nghĩ có nhiều điều hơn, hãy xem những gì anh ấy trả lời. Tôi gần như chắc chắn anh ta chỉ cần chuyên tập hợp các phương thức 'Foo' chứ không phải toàn bộ lớp. – vladr

+0

Tôi thích giải pháp, nhưng tôi nghĩ rằng nó khá hackish để đặt "mã trường hợp đặc biệt" trong giao diện công cộng và tất cả các mã chung trong cơ sở. Chắc chắn có một cách tốt hơn! –

1

Điều này được gọi là chuyên môn hóa một phần mẫu. Nó trông giống như thế này:

template<typename _T, size_t num> 
class FooBase 
{ 
}; 

template <typename _T, size_t num> 
class Foo : public FooBase<_T,num> 
{ 
    void Func() 
    { 
     printf("Hello world!"); 
    } 
}; 


template <typename _T> 
class Foo<_T,1> : public FooBase<_T,num> 
{ 
    void Func() 
    { 
     printf("Hi!"); 
    } 
} 
+0

Tôi không muốn sao chép toàn bộ nội dung của Foo (có nhiều phương pháp khác trong đó mà tôi đã bỏ qua) trong mỗi chuyên môn. –

+0

Đã chỉnh sửa để cho phép các hàm trong lớp cơ sở. –

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