我有以下课程;
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++ partial method specialization似乎更相关,但它建议专门研究整个班级(在我的案例中这是非常大的)。是否可以专门化整个班级,但实际上只专注于这一种方法?
答案 0 :(得分: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
}
答案 1 :(得分: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();
}
答案 2 :(得分:1)
简短的回答是“你没有”。
让您轻松完成自己想做的事情(让randomA
对N=1
采取不同的行为)的方法是将const TransitionMatrixTemplate<N, M> randomA()
填充到CRTP父级中,然后部分专门化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
无法编译的代码(反之亦然)。