在另一个模板中使用一个模板声明的默认模板参数

Use default template parameter of one template declaration in another

假设我有一个带有一些默认模板参数的 class 模板 cls1 和另一个使用 cls1:[=29 的 class 模板 cls2 =]

template<typename T1, typename T2 = int, typename U = std::vector<T1>>
class cls1 {};

template<typename T1, typename T2 = int, typename U = std::vector<T1>>
class cls2 : public cls1<T1, T2, U> {};

现在,如果我想更改某些 cls1 模板参数的默认值,我还需要 手动 在 [=14] 中更改它=] 为了保持一致性。

我已经考虑过使用类型别名(或者在非类型模板参数的情况下使用 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 T2 = cls1_default_t_2, typename U = cls1_default_u_t<T1>>
class cls2 : public cls1<T1, T2, U> {};

现在我只需要改变cls1_default_t_2cls1_default_u

但是,这有点冗长,具体取决于默认参数的数量。此外,如果我现在想制作另一个 class 模板 cls3 使用 cls2,使用 cls1 的默认参数是不利的,因为 cls1 cls3其实并没有直接使用。相反,我再次需要为 cls2 的默认模板参数提供类型别名(和 constexprs),以便在 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, T2, U> {};

template<typename T1, typename T2 = cls2_default_t_2, typename U = cls2_default_u_t<T1>>
class cls3 : public cls2<T1, T2, 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_typestd::vector<int> 而不是您要求的 tempalte <typename T> std::vector<T>。如果需要,您需要编写一个小助手。