我正在尝试编写一个智能指针包装器(包含 boost shared_ptr 或 scoped_ptr 或另一个智能指针包装器);每种包装器类型都注入了一些额外的功能(例如,记录使用情况、惰性初始化、验证正确的构造/销毁顺序等),但我希望它们对用户尽可能不可见(这样我就可以换入/换出包装器只需更改单个 typedef,可能还有一些构造函数代码,但没有使用代码)。
正常使用是微不足道的:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef typename T::value_type value_type;
...
value_type* get() { /*do something magic*/ return m_ptr.get(); }
const value_type* get() const { /*do something magic*/ return m_ptr.get(); }
// repeat for operator->, operator*, and other desired methods
private:
T m_ptr;
};
typedef some_smart_ptr_wrapper< boost::shared_ptr<int> > smart_int;
smart_int p;
(现在所有其他代码都可以p
与 shared_ptr 毫无区别地使用,至少对于定义的操作,我可以通过更改 typedef 添加额外的包装器。)
只需按照您的期望嵌套它们,就可以同时使用多个包装器,并且只有声明(有时初始化)变量的代码需要关心。
有时,虽然能够从包装器中获取“基本” shared/scoped_ptr 很有用(特别是将 shared_ptr 作为参数传递给不需要触发包装器添加的功能的函数);对于单个包装层很容易:
T& getPtr() { return m_ptr; }
const T& getPtr() const { return m_ptr; }
但这并不能很好地扩展到多个包装层(调用者必须执行p.getPtr().getPtr().getPtr()
正确的次数)。
我想做的是声明 getPtr() 这样:
- 如果 T 实现 getPtr(),则它返回 m_ptr.getPtr()(无论是什么类型)。
- 如果 T 没有实现 getPtr(),则返回 m_ptr。
- 正如您所期望的,它仍然有 const 和 non-const 两种风格。
其最终结果是从外部代码对 getPtr() 的单个调用将“向上”链到原始智能指针,因为这将是唯一不实现 getPtr() 的。
我相当确定该解决方案将涉及 SFINAE 和 boost::enable_if; 我有一点尝试让类似的东西发挥作用,但到目前为止还没有多少运气。
解决方案或完全替代的方法都受到欢迎;请注意,我希望它在 VC++2008 和 GCC 中都可以工作(遗憾的是,没有 C++11)。