我有基本类型
template<int p>
struct Base {};
以及基于许多版本的Base构建的更复杂的内容(有些是int模板,有些是类模板):
template<template<auto inner> typename basetype, typename p, typename q>
struct Complex {};
然后,我像这样创建变量:
Complex<Base, Base<1>, Base<2>> c;
有没有办法推断我的第一个模板参数是Base
,或者p
和q
是basetype
的专门版本,所以我可以写
Complex<Base<1>, Base<2>> c;
我想没有。但是模板有时会隐藏一些魔术。
答案 0 :(得分:9)
如果您希望Complex
的两个参数始终是同一模板的特化,则可以使用部分特化来实现:
// the primary template remains incomplete, so most uses of it will be an error
template <class T, class U> struct Complex;
template <template<auto> typename basetype, auto p_arg, auto q_arg>
struct Complex<basetype<p_arg>, basetype<q_arg>> {
// ...
};
实例化Complex<Base<1>, Base<2>>
时,参数basetype
,p_arg
和q_arg
将推导为Base
,1
和{ {1}}。
答案 1 :(得分:0)
是的,假设仍然可以选择手动输入基类模板的选项,则可以通过少量修改自动推断基类模板。
应该更改模板参数的顺序,以允许从默认参数推断基类模板:
template<typename p, typename q, template<auto> class basetype = Complex_helper<p, q>::template base>
struct Complex {};
并添加一个辅助模板,如:
template<template<auto> class basetype, auto p, auto q>
struct Complex_helper<basetype<p>, basetype<q> >{
template<auto x>
using base = basetype<x>;
};
(通过使用专业化)将为Base
(base
)提供alias template,或者如果两个类型参数都由相同的驱动,则将提供任何其他类模板类模板。
将它们放在一起:
template<int p>
struct Base {};
template<int p>
struct Another_Base {};
template<typename, typename>
struct Complex_helper;
template<template<auto> class basetype, auto p, auto q>
struct Complex_helper<basetype<p>, basetype<q> >{
template<auto x>
using base = basetype<x>;
};
template<typename p, typename q, template<auto> class basetype = Complex_helper<p, q>::template base>
struct Complex {};
Complex<Base<1>, Base<2> > object1;
Complex<Another_Base<7>, Another_Base<8> > object2;
Complex<Base<5>, Base<8>, Base> object3;
Complex<Another_Base<2>, Another_Base<9>, Another_Base> object4;
Complex<Base<78>, Base<87>, Another_Base> object5;
Complex<Another_Base<29>, Another_Base<92>, Base> object6;
如您所见,您也可以手动输入班级模板。
祝你好运!