4

我有以下课程;

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

现在我想专门randomA研究 N=1 的方法。我该怎么做?

我尝试关注这个问题:Template specialization of a single method from a templated class,但它似乎不适用于部分专业化。这个问题:C++ 部分方法专业化似乎更相关,但它建议专门化整个类(在我的情况下相当大)。是否可以专门化整个班级,但实际上只专门化这一种方法?

4

3 回答 3

6

我想专门randomA研究 N=1 的方法。我该怎么做?

您发现不允许对函数进行部分特化。

但是,您可以完全专门化代码的“详细”实现。

  template<int TheN>
  detail_randomA();

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

在类声明之外:

  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
  }
于 2013-04-23T16:05:34.410 回答
2

您不能部分专门化函数模板,但可以将工作交给模板。这是一个完整的工作示例:

#include<iostream>
using namespace std;

// This first template isn't important, it's 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();
}
于 2013-04-23T17:02:59.627 回答
1

简短的回答是“你没有”。

一种使您想做的事情变得容易的randomA方法N=1const TransitionMatrixTemplate<N, M> randomA()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
}

这仅在无法编译的代码(反之亦然)时才重要。N==1

于 2013-04-23T16:12:20.260 回答