을 결합 :: :표준 : 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_ptr
을 std::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
으로 지정할 유형을 말할 수 있습니까?
포인터가 'int'에 맞지 않으면 어떻게됩니까? 'sizeof (T *)> sizeof (int)'이면? 왜 단순히'& p [i]'를 사용하지 않는가? –
글쎄, 내가 코드에서 좀 더 복잡하게 썼다. 그리고 기본적으로 의도대로 작동한다. 요점은 std :: get_deleter에 지정할 유형을 모르겠습니다. – RazzorFlame
실제 코드에서'int (p)'와 같은 캐스트를 사용하지 않기를 희망합니다. *** ***은 모든 64 비트 시스템을 망가뜨릴 것입니다. –