2010-02-28 2 views
6

Aşağıda aşağıdakine benzer bir şeye benzeyen bir şablon sınıfına sahip olmak istiyorum. Daha sonra, bir CLASS şablon parametresine bağlı olarak şablon uzmanlığıyla bir işlev istiyorum. Bu işi nasıl yaparım? Sağladığım kodun birçok düzeyde yanlış olduğunu anlıyorum, ancak sadece kavramı açıklamak.Şablon sınıfı, işlev uzmanlığı

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!"); 
    } 
}; 

cevap

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

Bu çözümü beğendim. Hatta C++ adlandırma kuralı hakkında bir şeyler öğrendim! Ancak, bunların hiçbiri işe yaramazsa geri sayımla birlikte çeşitli sayı değerleri için herhangi bir sayıda uzmanlığa sahip olursam bunu nasıl yapabilirim? –

+0

@wowus, güncellenen yanıt –

+0

Teşekkür ederiz, kabul edilir. –

2

Orada fonksiyonu şablonlar hiçbir kısmi uzmanlık vardır ve kısmen kısmen sınıf şablonunu uzmanlaşmak ilk gereken bir üyeyi uzmanlaşmak.

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

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

Şimdi Foo eğer ayrıca, uygulama num değeri bağımsızdır Func dışındaki yöntemler içerir ve Foo uzmanlık onların uygulanmasını çoğaltmak istemiyorum, aşağıdaki modeli uygulayabilirsiniz: CRTP kullanarak

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() { 
    ... 
    } 
}; 

Veya:

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

Bu OP sadece Bence bunun için sözdizimi yazma bilmeyen bu durumda uzman olan bir sınıftır. –

+1

Bence daha fazlası var, ne cevap verdiğini görelim. Tam olarak sadece Foo'nun yöntemlerinin bir alt kümesini uzmanlaştırması gerektiği konusunda eminim. – vladr

+0

Çözümü beğendim, ancak genel arayüzde "özel durum kodu" nu ve tabandaki tüm genel kodu koymak oldukça zahmetli olduğunu düşünüyorum. Elbette daha iyi bir yol var! –

1

Bu kısmi şablon uzmanlığı denir. Bu şuna benzer:

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

Her uzmanlıkta Foo'nun tamamını (ihmal ettiğim birçok başka yöntem var) çoğaltmak istemiyorum. –

+0

Bir temel sınıftaki işlevlere izin vermek için düzenlenmiştir. –