C++中如何将类内嵌套类作为基类模板参数传入?
解决方案
最干净且完全符合你需求的实现方式是使用CRTP(奇异递归模板模式),不需要把嵌套类挪到外部命名空间,也不会触发不完整类型的未定义行为。
实现原理
C++标准规定,类模板中依赖模板参数的类型查找、成员实例化会延迟到模板实际实例化的节点——也就是派生类完整定义结束的位置,这时候派生类内部的嵌套类已经完成定义,完全可以被正常访问。
代码实现
#include <memory> template <class Derived> class shared_class { protected: // 嵌套类型的查找延迟到实例化阶段,此时Derived的完整定义已可见 std::shared_ptr<typename Derived::C> d = std::make_shared<typename Derived::C>(); typename Derived::C* container() { return d.get(); } }; class A : public shared_class<A> { // 给基类开放访问权限,因为C是私有嵌套类 friend class shared_class<A>; class C { // 嵌套类完全定义在A内部,不暴露到外部命名空间 public: int i = 0; }; public: // 测试访问 void set(int v) { d->i = v; } int get() { return container()->i; } };
说明
- 这个实现完全满足要求:嵌套类
C的完整定义完全被包含在A的类定义内部,不会污染外部命名空间,实现细节完全对外隐藏。 - 整个流程完全符合C++标准:
std::shared_ptr本身就支持不完整类型的前置声明场景,而实际调用make_shared实例化对象时,C已经是完整类型,不存在任何未定义行为。 - 唯一需要额外添加的是友元声明,因为默认情况下基类没有权限访问派生类的私有嵌套类。
内容的提问来源于stack exchange,提问作者daedsidog
相关产品推荐
相关产品推荐

