编译时选择性继承Typedef的C++技术解决方案问询
问题分析
你遇到的歧义问题根源在于:类C同时继承了TypesDefs<C>和A(而A本身继承了TypesDefs<A>),两个不同实例化的TypesDefs基类都定义了名为ptr的类型别名,编译器无法自动确定你要引用的是哪一个。
以下是几个符合你原有逻辑的解决方案:
方案1:在派生类中显式指定目标别名
在类C中直接通过using声明明确指定要使用的ptr别名,覆盖歧义的名称:
class C: public TypesDefs<C>, public A { public: // 明确指定使用当前类对应的ptr别名 using ptr = TypesDefs<C>::ptr; };
这样C::ptr会直接指向std::shared_ptr<C>,如果需要访问A的指针类型,可以直接写A::ptr或TypesDefs<A>::ptr。
方案2:将类型定义隔离到嵌套作用域
修改TypesDefs模板,把所有类型别名放到一个嵌套结构体中,从根源上避免同名冲突:
template<class Derived> class TypesDefs { public: struct TypeAliases { using ptr = std::shared_ptr<Derived>; // ... 更多类型定义都统一放在这里 }; };
之后使用类型别名时,需要通过嵌套结构体访问:
A的指针类型:A::TypeAliases::ptrC的指针类型:C::TypeAliases::ptr
这种方式彻底消除了同名冲突的可能,同时保持了类型定义的集中管理。
方案3:利用CRTP特性隐藏基类同名成员
如果希望保留ptr的直接访问方式,可以修改TypesDefs的继承权限,并在派生类中通过this指针限定访问:
template<class Derived> class TypesDefs { protected: using ptr = std::shared_ptr<Derived>; // ... 更多类型定义 }; // 使用时通过this->ptr访问,编译器会优先匹配当前类的基版本 class C: public TypesDefs<C>, public A { public: void func() { // 明确使用当前类的ptr类型 typename std::remove_reference_t<decltype(*this)>::ptr p; } };
这种方式不需要修改原有类型定义的结构,但使用时需要额外的类型限定。
内容的提问来源于stack exchange,提问作者SpeakX
相关产品推荐
相关产品推荐

