我不清楚在偏特化上下文中默认模板参数的交互,以选择哪个是更好的匹配模板。此问题源于此 answer 中发布的代码通过 max66。
给定类的定义 A
和 B
:
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>>
, 特化 yield 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>>
.
然后我们尝试将其与“更好的实例化”相匹配。
我们可以选择:
// 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更专业,所以选择它。
关于c++ - 默认模板参数在偏特化上下文中的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52583833/