如何无需模板实参即可访问模板独立的内部子类型?
解决模板结构体中无关模板的内部枚举引用问题
假设我们有如下模板结构体定义:
template <typename TPoint> struct Plane { enum class PointPosition // 与Plane高度相关,定义在此很合理 { InFront, Behind, On }; PointPosition position_of(TPoint p) const { // ... } };
在外部调用时,必须指定完整的模板实参才能引用内部枚举,写法非常繁琐:
void handle(Plane<glm::dvec3> p) { switch (p.position_of(my_point)) { case Plane<glm::dvec3>::PointPosition::On: // 冗余的模板参数指定 // ... } }
我们希望简化引用方式,且不破坏枚举与Plane的关联关系。除了你提到的几种方案外,还有以下可行技巧:
方案1:利用decltype推导实例类型
在使用枚举的函数内部,通过参数的类型推导枚举所属的模板特化类型,避免重复书写模板参数:
void handle(Plane<glm::dvec3> p) { using PointPos = decltype(p)::PointPosition; switch (p.position_of(my_point)) { case PointPos::On: // 处理逻辑 break; case PointPos::InFront: // ... break; } }
这种方式无需修改Plane的定义,仅在使用处做局部类型别名,既简洁又保留了枚举与Plane的关联。
方案2:将枚举移至非模板基类
创建一个非模板的基类存放枚举,让Plane模板继承该基类。这样枚举既属于Plane的关联类型体系,又可以直接通过基类名引用:
// 存放枚举的非模板基类,与Plane强关联 struct PlaneCore { enum class PointPosition { InFront, Behind, On }; }; template <typename TPoint> struct Plane : PlaneCore { PointPosition position_of(TPoint p) const { // 实现逻辑 } };
使用时直接写PlaneCore::PointPosition::On即可,Plane的成员函数返回的枚举类型与基类完全一致,不存在类型不匹配问题。基类的命名可以根据需求调整(比如PlaneBase),确保语义上与Plane紧密关联。
方案3:给模板设置默认参数(C++11及以上)
如果可以为Plane模板指定合理的默认参数,就能通过Plane<>省略模板实参来引用枚举:
// 为模板参数设置默认值 template <typename TPoint = glm::dvec3> struct Plane { enum class PointPosition { InFront, Behind, On }; PointPosition position_of(TPoint p) const; };
此时可以直接写Plane<>::PointPosition::On,这种写法保留了枚举在Plane内部的结构,仅依赖一个默认模板参数,适合有通用默认类型的场景。
内容的提问来源于stack exchange,提问作者Fantastic Mr Fox
相关产品推荐
相关产品推荐

