为何Visual C++ 6无法编译含模板自引用友元的shared_ptr代码?
这个语法的核心目的是允许不同模板参数实例化的shared_ptr类互相访问私有成员。
shared_ptr的常用场景需要支持兼容类型的隐式转换,比如将shared_ptr<派生类>赋值给shared_ptr<基类>,或者从shared_ptr<U>构造shared_ptr<T>的场景。这类转换逻辑需要访问另一个shared_ptr实例的私有成员(比如内部存储的裸指针、引用计数指针等),而shared_ptr<T>和shared_ptr<U>是完全独立的两个模板实例,默认没有访问权限。
通过声明template<class U> friend class shared_ptr;,相当于告诉编译器:所有任意参数U实例化出来的shared_ptr<U>类,都是当前shared_ptr<T>类的友元,不管U和T是什么类型,都可以互相访问私有成员。
实际使用示例如下:
template<class T> class shared_ptr { T* ptr; int* ref_count; // 所有shared_ptr实例互为友元 template<class U> friend class shared_ptr; public: // 支持从其他类型的shared_ptr构造 template<class U> shared_ptr(const shared_ptr<U>& other) { // 直接访问other的私有成员,没有友元声明此处会编译失败 ptr = other.ptr; ref_count = other.ref_count; (*ref_count)++; } // 其余接口省略 };
VC6是1998年C++标准刚发布时推出的编译器,其模板解析器的标准合规性非常差,对模板友元的支持存在大量固有缺陷。
你遇到的语法错误是VC6的已知限制:它的解析器无法识别「正在定义的模板类,以任意其他模板参数作为自身友元」的声明写法,遇到template<class U> friend class shared_ptr;时,会错误地将shared_ptr识别为未定义的外部类,解析到<符号时直接抛出语法错误,不支持这种标准允许的模板友元声明写法。
你选择使用Boost 1.34.1规避问题是合理的,该版本的Boost专门针对VC6做了大量兼容适配,通过其他语法绕开了这类不被VC6支持的模板特性。
内容的提问来源于stack exchange,提问作者Zhro

