2016-10-08 3 views
0

을 결합 :: :표준 : 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::bind으로 초기화했기 때문입니다. std::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을 초기화 한 직후에 deleter를 얻으려고 노력했다. 그러나 함수에서 같은 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 &> * 

는 말을 살펴보십시오 - 추가적인 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; 
관련 문제