问题描述
假设我有一个带有一些默认模板参数的类模板cls1
和另一个使用cls2
的类模板cls1
:
template<typename T1,typename T2 = int,typename U = std::vector<T1>>
class cls1 {};
template<typename T1,typename U = std::vector<T1>>
class cls2 : public cls1<T1,T2,U> {};
现在,如果我想更改cls1
模板参数中的某些默认值,则还需要手动在cls2
中进行更改以保持一致性。
我已经考虑过使用类型别名(对于非类型模板参数,则使用constexpr
变量):
using cls1_default_t_2 = int;
template<typename T1>
using cls1_default_u = std::vector<T1>;
template<typename T1,typename T2 = cls1_default_t_2,typename U = cls1_default_u_t<T1>>
class cls1 {};
template<typename T1,typename U = cls1_default_u_t<T1>>
class cls2 : public cls1<T1,U> {};
现在,我只需要更改cls1_default_t_2
或cls1_default_u
。
但是,这有点冗长,取决于默认参数的数量。另外,如果我现在想让另一个类模板cls3
使用cls2
,则不宜使用cls1
的默认参数,因为实际上cls1
不是直接由cls3
使用。相反,我再次需要为constexpr
的默认模板参数提供类型别名(和cls2
),以便在cls3
中使用它们:
// ... cls1 as seen above
using cls2_default_t_2 = cls1_default_t_2;
template<typename T1>
using cls2_default_u_t = cls1_default_u_t<T1>;
template<typename T1,typename T2 = cls2_default_t_2,typename U = cls2_default_u_t<T1>>
class cls2 : public cls1<T1,U> {};
template<typename T1,typename U = cls2_default_u_t<T1>>
class cls3 : public cls2<T1,U> {};
那么,在一个模板声明中使用默认模板参数在另一个模板声明中是否有更简洁的表示法?
解决方法
我认为没有办法完全避免冗长。与函数默认参数类似,如果不付出额外的努力,就无法真正使用模板默认参数。这是我能想到的最好的方法:
template<typename T1,typename T2 = int,typename U = std::vector<T1>>
class cls1 {
using value_type = T2;
using container_type = U;
};
template<typename T1,typename T2 = typename cls1<T1>::value_type,typename U = typename cls1<T1>::container_type>
class cls2 : public cls1<T1,T2,U> {};
拥有别名不仅对默认参数有好处,所以也许这并不是真正的“额外”工作。
请注意,container_type
不是您要求的std::vector<int>
,而是tempalte <typename T> std::vector<T>
。如果需要,您将需要编写一个小助手。