如何部分专门化类模板非类型参数

时间:2018-12-03 04:26:09

标签: c++ templates partial-specialization class-template

我的问题很基本。我试图给自己一个方便的类模板实例化,该实例化在数学上很直观。我希望能够通过将其实例化为Q<0,31>来实例化名为Q<31>的类。根据cppreference.com,此should be possible

template<class T> 
class A<int, T*, 5> {}; // #3: partial specialization where T1 is int, I is 5,
                        //     and T2 is a pointer

但是当我尝试这样做时:

template< unsigned integral, unsigned fractional >
class Q: public Signed<integral + fractional + 1u> {};

// There's a shorthand for Q notation where you don't specify the number of integer bits, and it's assumed to be 0
template< unsigned fractional > class  Q<0u, fractional>: public Signed<fractional + 1> {};

static_assert( std::is_same< Q<31>, Q<0,31> >::value, "Partial specialization should be equivalent to no integer component");

然后我收到一条错误消息,说我没有传递足够的模板参数

2 个答案:

答案 0 :(得分:1)

专业化不是重载。它们是模式匹配。

缺少魔术值,没有办法像您想要的那样“重载”模板。

template< unsigned fractional >
class  Q<0u, fractional>

这只是图案匹配。

您的参数总是

template< unsigned integral, unsigned fractional >
class Q

,当某人通过0u并获得integral时,您的专业将匹配。如此匹配

Q<0u, fractional>

不匹配

Q<fractional>

现在,如上所述,您可以使用魔术值来做到这一点:

template< unsigned integral, unsigned fractional=-1 >
class Q
template< unsigned fractional >
class Q<fractional, -1>:Q<0u, fractional> {}

但是如果有人手动通过-1,也会发生这种情况。

中,您可以将用户定义的类型作为模板非类型模板参数,因此您可以执行以下操作:

template< unsigned A, optional<unsigned> B = {} >
class Q;

template< unsigned integral, unsigned fractional >
class Q< integral, optional<unsigned>(fractional) > // 2 arg case

template< unsigned fractional >
class Q< fractional, nullopt >:Q<0u, fractional> {}; // 1 arg case

但是这里还没有。

答案 1 :(得分:1)

您无法以所需的方式实现它,因为正如已经说过的那样,它并不重载,但是它可以通过带有部分专业化的别名模板来实现:

template<int, int B>
struct Q {};

template<int B>
using Q0 = Q<0,B>;

在您的代码中

static_assert( std::is_same< Q0<31>, Q<0,31> >::value, "Partial specialization should be equivalent to no integer component");

这将编译没有错误