C ++模板模板推断类型参数

时间:2019-05-24 14:28:57

标签: c++ templates

我有基本类型

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,或者pqbasetype的专门版本,所以我可以写

Complex<Base<1>, Base<2>> c;

我想没有。但是模板有时会隐藏一些魔术。

2 个答案:

答案 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>>时,参数basetypep_argq_arg将推导为Base1和{ {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>;
};

(通过使用专业化)将为Basebase)提供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;


如您所见,您也可以手动输入班级模板。

祝你好运!