なブーストのようないくつかのスマートポインタテンプレート、:: shared_ptrのは、任意のオブジェクトを保持するために、ボイドでインスタンス化することができる。voidでインスタンス化できるスマートポインタの実装方法は?
以下http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/sp_techniques.html#pvoid
は、最小限のscoped_ptrを実装です。 voidでインスタンス化されると、コンパイラは、逆参照演算子で不正な "voidへの参照"が形成されることについて不平を言う。 「代替失敗は誤りではない」(SFINAE)ルールはこのような状況をカバーしていないようです。
どのようにしてscoped_ptrを実装できますか?特に、テンプレートの専門化を書く代わりに、それがありますか?これにより、現実的なスマートポインタの実装による大きなコードの重複が発生します。
#include <cstdlib>
template<typename T>
void destroy(T* ptr)
{
delete ptr;
}
class scoped_ptr_impl_base
{
public:
virtual ~scoped_ptr_impl_base() { }
};
template<typename T, typename F>
class scoped_ptr_impl : public scoped_ptr_impl_base
{
public:
scoped_ptr_impl(T* ptr, F dtor)
: m_ptr(ptr), m_dtor(dtor)
{
}
virtual ~scoped_ptr_impl()
{
m_dtor(m_ptr);
}
private:
T* m_ptr;
F m_dtor;
};
template<typename T>
class scoped_ptr
{
public:
explicit scoped_ptr(T* ptr = 0)
: m_ptr(ptr),
m_impl(new scoped_ptr_impl<T, void (*)(T*)>(&destroy<T>))
{
}
template<typename F>
scoped_ptr(T* ptr, F dtor)
: m_ptr(ptr),
m_impl(new scoped_ptr_impl<T, F>(ptr, dtor))
{
}
~scoped_ptr()
{
delete m_impl;
}
T& operator*()
{
return *m_ptr;
}
T* operator->()
{
return m_ptr;
}
private:
T* m_ptr;
scoped_ptr_impl_base* m_impl;
scoped_ptr(const scoped_ptr&);
scoped_ptr& operator=(const scoped_ptr&);
};
int main()
{
scoped_ptr<void> p(std::malloc(1), std::free);
// scoped_ptr.cpp: In instantiation of `scoped_ptr<void>':
// scoped_ptr.cpp:76: instantiated from here
// scoped_ptr.cpp:56: error: forming reference to void
// (g++ 4.3.3)
return 0;
}
+1。私は「無効」が好きだった。これは、voidポインタを逆参照できる場合に得られるものです。とにかく、それは重要ではないでしょう。演算子*を呼び出そうとすると、void *の逆参照についてのエラーが発生するためです。 –
確かに、 'shared_ptr'(エラーと見なすべき)を逆参照しようとすると、エラーが発生するので、voidはvoid *よりも優れています。 –
合意し、元に戻しました。いつもあなたの最初の本能と一緒に行く... –