std :: get_deleter для std :: shared_ptr, инициализированный с помощью std :: bind

Допустим, у меня есть этот код:

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?

0

Решение

Оказалось, что компилятор неправильно переводил decltype. Я попытался получить delete сразу после инициализации 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;
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector