2016-10-08 20 views
0

比方说,我有这样的代码:的std :: get_deleter ::绑定

class BaseObject 
{ 
public: 
    virtual void OnDestroy() {} 
}; 
template <typename T> 
struct myArrayDeleter 
{ 
    void operator()(T *p, std::size_t count) 
    { 
     for(std::size_t i = 0; i < count; i++) 
     { 
      static_cast<BaseObject*>((void*)(int(p) + sizeof(T) * i))->OnDestroy(); 
     } 
     delete [] p; 
    } 
}; 

而且,我们假设它按预期工作(这是一个简化版本,现在写不检查,但基本上你知道这个代码应该做什么)。
用这部分我没有问题。但是,请检查:

class AActor 
    : public BaseObject 
{ 
public: 
    virtual void OnDestroy() override 
    { 
     // some code here 
    } 
}; 

template <typename T> 
class SimplifiedHolder 
{ 
protected: 
    std::shared_ptr<T> m_shared; 
    std::size_t m_size; 
public: 
    // Some not important code here 

    // WE ASSUME HERE THAT IT ALWAYS HOLDS ARRAY 
    // sizeOfArray always > 1 
    template <typename U> 
    SimplifiedHolder(U *ptr, std::size_t sizeOfArray) 
     : m_size(sizeOfArray) 
    { 
     m_shared = std::shared_ptr<T>(ptr, 
          std::bind(&myArrayDeleter<U>(), std::placeholders::_1, m_size)); 
    } 

    // And now as we initialize our shared_ptr with template 
    // we can check if it is exactly of type "U" 
    template <typename U> 
    bool IsExactlyOfType() 
    { 
     if(!m_shared) 
      return false; 

     return ((void*)std::get_deleter<myArrayDeleter<U>>(m_shared)) != nullptr; 
    } 
}; 

但是,方法IsExactlyOfType不起作用。那是因为我初始化了shared_ptrstd::bindstd::get_deleter总是返回nullptr,因为在模板中指定了错误的类型。我不知道要传递什么类型。我也试图与非阵列码,其中myDeleter是一个只有一个参数一个仿函数,并将其与代码工作完全是这样的:

template <typename U> 
bool IsExactlyOfType() 
{ 
    if(!m_shared) 
     return false; 

    return ((void*)std::get_deleter<myDeleter<U>>(m_shared) != nullptr; 
} 

我知道我可以用typeid(U) == typeid(*m_shared.get())去,但这不是我想要的。我有更复杂的代码,在这种情况下,只有这种方法是好的。

一个更有经验的程序员能告诉我什么类型可以指定为std::get_deleter

+0

在您的删除程序中,如果指针无法放入“int”中会怎么样?如果'sizeof(T *)> sizeof(int)'?为什么不简单使用'&p [i]'? –

+0

就像我在代码中写得相当复杂一样,它基本上按照预期工作,这不是重点。关键是我不知道要为std :: get_deleter指定哪种类型。 – RazzorFlame

+0

我仍然希望你在你的真实代码中不使用像int(p)这样的强制转换。它***将破解几乎所有的64位系统。 –

回答

0

原来,编译器没有正确翻译decltype。初始化shared_ptr后,我试图立即删除它并运行。然而,同样的decltype在功能上稍稍产生其他类型。我检查调试器,它产生的这种结果:

在构造函数中:

std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<APlayer>,std::_Ph<1> const &,unsigned int &> & 

在功能:

std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<APlayer>,std::_Ph<1> const &,unsigned int const &> * 

看看到底 - 它附加额外的常量。我需要手动更改它,所以现在我的代码如下所示:

using D = std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<U>, 
         std::_Ph<1> const &,unsigned int &>; 

return ((void*)std::get_deleter<D>(m_shared)) != nullptr;