如何在模板中为继承的模板基类定义别名并复用,简化构造调用
模板中复用基类类型以避免重复书写
问题描述
当模板参数列表较长时,在模板定义中多次重复输入继承的基类完整限定类型名,容易出现漏改情况,甚至可能编译通过但引发难以调试的错误。现需优化如下代码,避免重复书写基类类型,同时满足两个条件:
- 类继承自同名模板(模板名称相同,参数不同)
- 需要调用基类的构造函数
待优化代码示例:
template<int Index, typename ... Rest> struct Sequence { // ... }; template<int Index, typename F, typename ... Rest> struct Sequence<Index, F, Rest ...> : public Sequence<Index+1, Rest ...> { // 能否优化构造函数中重复书写的基类类型Sequence<Index+1, Rest ...> Sequence(int Param):Sequence<Index+1, Rest ...>(Param) { } };
解决方案
当然可以通过定义基类别名来实现复用,以下是几种简洁可行的方式:
1. 类内部使用using声明基类别名
在派生类定义中先声明基类的别名,后续所有需要引用基类的地方都可以直接使用别名,包括构造函数初始化列表:
template<int Index, typename ... Rest> struct Sequence { // ... }; template<int Index, typename F, typename ... Rest> struct Sequence<Index, F, Rest ...> : public Sequence<Index+1, Rest ...> { using Base = Sequence<Index+1, Rest ...>; Sequence(int Param): Base(Param) { } };
这种方式只需要在using处写一次基类完整类型,后续修改仅需改动这一处,能有效避免漏改问题。
2. 模板默认参数预定义基类(C++11及以上)
如果需要在更外层复用基类类型,可以通过模板默认参数预先定义,但这种方式相对繁琐,不如第一种直接:
template<int Index, typename ... Rest> struct Sequence { // ... }; template<int Index, typename F, typename ... Rest, typename Base = Sequence<Index+1, Rest ...>> struct Sequence<Index, F, Rest ...> : public Base { Sequence(int Param): Base(Param) { } };
使用时需注意默认参数的正确性,避免引发模板参数推导问题。
3. 构造函数委托(C++11及以上)
如果仅需简化构造函数的基类调用,可以使用构造函数委托,但这种方式仅适用于构造函数场景,无法解决其他需要引用基类类型的情况:
template<int Index, typename ... Rest> struct Sequence { // ... }; template<int Index, typename F, typename ... Rest> struct Sequence<Index, F, Rest ...> : public Sequence<Index+1, Rest ...> { using Sequence<Index+1, Rest ...>::Sequence; // 若需扩展构造逻辑,可在此添加自定义代码 Sequence(int Param): Sequence<Index+1, Rest ...>(Param) { // 自定义逻辑 } };
综上,在类内部用using声明基类别名是最简洁通用的方案,既能避免重复书写,又方便后续维护修改。
内容的提问来源于stack exchange,提问作者Boris
相关产品推荐
相关产品推荐

