2016-10-08 42 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;