Partial type specialization of one method of a larger class

I have the following class:

template<int N, int M, int K> class BaumWelch { //lots of stuff const TransitionMatrixTemplate<N, M> randomA() { //.... } } 

Now I would like to specialize the randomA method for N = 1. How can I do this?

I tried to answer this question: Template specialization for one method from a template class , but does not seem to work with partial specialization. This question: the specialization of the partial C ++ method seems to be more relevant, but it offers to specialize the whole class (which is quite large in my case). Is it possible to specialize the whole class, but actually specialize only this method?

+4
source share
3 answers

You cannot partially specialize function templates, but you can pass work into class templates. Here is a complete working example:

 #include<iostream> using namespace std; // This first template isn't important, it just the return value from your function template <int N, int M> struct TransitionMatrixTemplate { void print_me() const { cout << N << ',' << M << endl; } }; // We need to announce the existence of the BaumWelch class template early here, // in order that it can appear in the signature of our impl_randomA class. template<int N, int M, int K> struct BaumWelch; // Now, the first important bit of code. The default implementation template<int N, int M, int K> struct impl_randomA { static TransitionMatrixTemplate<N,M> f(BaumWelch<N,M,K> * This) { return TransitionMatrixTemplate<N,M>(); } }; // Next, is the partially specialized version. template<int M, int K> struct impl_randomA<1,M,K> { static TransitionMatrixTemplate<1,M> f(BaumWelch<1,M,K> * This) { cout << "<Special for N=1> "; return TransitionMatrixTemplate<1,M>(); } }; // Finally, The BaumWelch class and its call out to impl_randomA. template<int N, int M, int K> struct BaumWelch { const TransitionMatrixTemplate<N, M> randomA() { return impl_randomA<N,M,K> :: f(this); } }; int main() { BaumWelch<2,3,4>() . randomA() . print_me(); BaumWelch<1,3,4>() . randomA() . print_me(); } 
+2
source

I would like to highlight the randomA method for N = 1. How can I do this?

You have discovered that partial specialization is not allowed for functions.

However, you can fully specialize in "detailing" code implementation.

  template<int TheN> detail_randomA(); const TransitionMatrixTemplate<N, M> randomA() { return detail_randomA<N>(); } 

And outside the class declaration:

  template<int N, int M, int K> template<int TheN> BaumWelch<N,M,K>::detail_randomA() { //lots of stuff when N != 1 } template<int N, int M, int K> template<> BaumWelch<N,M,K>::detail_randomA<1>() { //lots of stuff when N == 1 } 
+6
source

The short answer is "you do not."

To simplify the implementation of what you want to do ( randomA act differently for N=1 ), you would need to write const TransitionMatrixTemplate<N, M> randomA() in the parent CRTP element, and then partially specialize this for N=1 .

 template<typename D, int N, int M, int K> struct Bob_Base { static_assert( std::is_base_of< D, Bob_Base<D, N, M, K> >::value, "D must be derived from Bob_Base" ); D* self() { return static_cast<D*>(this); D const* self() const { return static_cast<D*>(this); const TransitionMatrixTemplate<N, M> randomA() { // use self()-> instead of this-> in here to access Bob methods and date } }; template<typename D,int M, int K> struct Bob_Base< D, 1, M, K > { static_assert( std::is_base_of< D, Bob_Base<D, N, M, K> >::value, "D must be derived from Bob_Base" ); D* self() { return static_cast<D*>(this); D const* self() const { return static_cast<D*>(this); const TransitionMatrixTemplate<1, M> randomA() { /* N=1 version */ } }; template<int N, int M, int K> struct Bob : Bob_Base<Bob<N, M, K>, N, M, K> { //lots of stuff, but no TransitionMatrixTemplate } 

this is important only if the code where N==1 cannot compile (or vice versa).

+1
source

All Articles