首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现可以用void实例化的智能指针?

如何实现可以用void实例化的智能指针?
EN

Stack Overflow用户
提问于 2009-08-21 15:08:16
回答 1查看 1.9K关注 0票数 4

某些智能指针模板,如boost::shared_ptr,可以使用空来实例化以容纳任意对象:

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/sp_techniques.html#pvoid

下面是一个最小的scoped_ptr实现。当使用void实例化时,编译器会抱怨在取消引用操作符中形成了非法的“void引用”。似乎“替换失败不是一个错误”(SFINAE)规则并不涵盖这种情况。

那么,如何实现scoped_ptr呢?具体地说,除了编写模板专门化之外,还有其他选择吗?对于实际的智能指针实现,这将导致大量的代码重复。

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-08-21 15:24:00

您可以为引用类型使用类型特征:

代码语言:javascript
复制
template<typename T>
struct type_trait
{
    typedef T& reference;
};

template<>
struct type_trait<void>
{
    typedef void reference;
};

然后在你的scoped_ptr_impl中:

代码语言:javascript
复制
typename type_trait<T>::reference operator*()
{
    return *m_ptr;
}

不过,我不确定void是否是专门化中的正确类型。您希望它返回什么类型?

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1312540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档