Скажем, у меня есть этот код:станд :: get_deleter на станд :: shared_ptr инициализируется станд :: связать
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-битные системы. –