默认模板参数在偏特化上下文中的作用

Role of default template arguments in the context of partial specialization

我不清楚偏特化上下文中默认模板参数的交互,以选择哪个是更好的匹配模板。此问题源于 max66.

在此 中发布的代码

给定 类 AB 的定义:

template <int N> struct A { static const int code = N; };

struct B{};

和以下模板 类:

// primary template
template <typename, typename Enable = bool_constant<true>>
struct cond : public bool_constant<false> {};

// specialization
template <typename T>
struct cond<T, bool_constant<(0 == T::code)>> : public bool_constant<true> {};

1) cond<B>::value 的计算结果为 false(即选择了主要)。这很明显,因为主模板产生 cond<B, bool_constant<true>>,特化失败,因此主模板是唯一可能的选择。

2) cond<A<0>>::value 的计算结果为 true(即选择了专业化)。这很明显,因为主模板产生 cond<B, bool_constant<true>>,特化也产生 cond<B, bool_constant<true>>,因此特化是首选,因为明确给出了第二个模板参数的参数。

3) cond<A<1>>::value 的计算结果为 false(即选择了主要)。我不清楚。主模板产生 cond<B, bool_constant<true>>,专业化产生 cond<B, bool_constant<false>>。鉴于第二个模板参数的参数在专业化中明确给出,为什么不首选?

我想 (3) 中的行为是由于主模板的默认模板参数与特化之间的某种交互作用所致。在此 answer 中,Jerry Coffin 陈述了一些可以解释此行为的内容:

if we change the specialization so that its specialization is for a type other than the default provided by the base template then the base template will be chosen.

有人可以详细说明这条规则吗?谢谢

template <typename, typename Enable = bool_constant<true>>
struct cond : public bool_constant<false> {};

等同于

template <typename, typename Enable = bool_constant<true>> struct cond;

template <typename, typename Enable>
struct cond : public bool_constant<false> {};

稍后可能会更清楚地理解结果。

当你写cond<C>时,由于默认参数,它等同于cond<C, bool_constant<true>>

然后我们尝试将其匹配到 "better instantiation".

我们可以选择:

// primary template
template <typename, typename Enable>
struct cond : public bool_constant<false> {};

和使用 SFINAE 的部分专业化:

// specialization
template <typename T>
struct cond<T, bool_constant<(0 == T::code)>> : public bool_constant<true> {};

如果 0 == T::code 格式不正确,专业化将被丢弃,只有主模板是可行的解决方案,因此使用它。

否则,如果 0 == T::code 的计算结果为 false,则专业化不匹配,并且还使用主模板。
请注意,在这种情况下,使用 cond<C, bool_constant<false>> 将使用专业化。

否则,0 == T::code的计算结果为true,那么primary和specialization都可行,但是specialization更专业,所以选择了