Sagen wir, ich habe diesen Code:std :: get_deleter auf std :: shared_ptr mit std initialisiert ::
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;
}
};
Und nehmen wir an, dass es wie vorgesehen funktioniert (es ist eine vereinfachte Version, geschrieben jetzt ohne die überprüfe aber im Grunde weißt du, was dieser Code tun soll).
Mit diesem Teil habe ich kein Problem. Aber check this out:
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;
}
};
Jedoch ist das Verfahren IsExactlyOfType
nicht funktioniert. Das liegt daran, dass ich mit std::bind
initialisiert habe. std::get_deleter
gibt immer nullptr
zurück, da der falsche Typ in der Vorlage angegeben ist. Ich weiß nicht, welchen Typ ich weitergeben soll. Ich habe auch versucht mit Nicht-Array-Code, in dem myDeleter
ein Funktor mit nur einem Argument ist, und es funktioniert perfekt mit dem Code wie folgt aus:
template <typename U>
bool IsExactlyOfType()
{
if(!m_shared)
return false;
return ((void*)std::get_deleter<myDeleter<U>>(m_shared) != nullptr;
}
Ich weiß, dass ich mit typeid(U) == typeid(*m_shared.get())
gehen könnte, aber das ist nicht das, was ich will. Ich habe viel komplizierteren Code und in diesem Fall ist nur diese Methode gut.
Kann ein erfahrener Programmierer mir sagen, welche Art zu std::get_deleter
angeben?
In Ihrem Deleter, was, wenn ein Zeiger nicht in ein 'int' passen kann? Wenn 'sizeof (T *)> sizeof (int)'? Warum nicht einfach '& p [i]' benutzen? –
Nun, wie ich schrieb, ist es im Code ziemlich kompliziert, und es funktioniert im Grunde wie beabsichtigt und das ist nicht der Punkt hier. Der Punkt ist, ich weiß nicht, welcher Typ für std :: get_deleter angegeben werden soll. – RazzorFlame
Ich hoffe immer noch, dass Sie nicht einen Cast wie 'int (p)' in Ihrem echten Code verwenden. Es wird *** fast alle 64-Bit-Systeme durchbrechen. –