考虑一种情况,需要在另一个模板的虚拟参数中T
使用另一个模板g
(例如,可能是某个表达式)验证类型,如下所示:enable_if
template<class> struct g { typedef void type; };
template<class, class> struct f {};
template<class T> struct f<T, void> {}; // Case A
template<class T> struct f<T*, typename g<T>::type> {}; // Case B
int main() { f<int*, void> test; }
在这里,为了简单起见g
并没有真正做任何事情。案例 B中的第二个参数是在非推导的上下文中,因此直觉上人们会认为案例 B比案例 A更专业。可悲的是,gcc 和 clang 都会抱怨模板在上面的实例化中不明确。
如果要删除虚拟参数,那么它编译得很好。T*
添加非推导参数如何以某种方式破坏比 更专业的合理期望T
?
这是使用替换算法的快速检查:
f<Q , void >
-> f<T*, g<Q>::type> // [failed]
f<Q*, g<Q>::type>
-> f<T , void > // [to fail or not to fail?]
// One would assume that 2nd parameter is ignored, but guess not?