Что такое стирание типов в C++?
Итак, я читал эта статья о стирании типа. Но код в этой статье, кажется, частично ошибочные, например:
template <typename T>
class AnimalWrapper : public MyAnimal
{
const T &m_animal;
public:
AnimalWrapper(const T &animal)
: m_animal(animal)
{ }
const char *see() const { return m_animal.see(); }
const char *say() const { return m_animal.say(); }
};
следовал по
void pullTheString()
{
MyAnimal *animals[] =
{
new AnimalWrapper(Cow()), /* oO , isn't template argument missing? */
....
};
}
эти ошибки обескуражили меня от дальнейшего чтения статьи.
В любом случае; может ли кто-нибудь научить, какой тип стирания в C++ означает, с простыми примерами?
Я хотел узнать об этом, чтобы понять, как std::function
работает, но не могу получить мою голову вокруг он.
1 ответов
вот очень простой пример стирания типа в действии:
// Type erasure side of things
class TypeErasedHolder
{
struct TypeKeeperBase
{
virtual ~TypeKeeperBase() {}
};
template <class ErasedType>
struct TypeKeeper : TypeKeeperBase
{
ErasedType storedObject;
TypeKeeper(ErasedType&& object) : storedObject(std::move(object)) {}
};
std::unique_ptr<TypeKeeperBase> held;
public:
template <class ErasedType>
TypeErasedHolder(ErasedType objectToStore) : held(new TypeKeeper<ErasedType>(std::move(objectToStore)))
{}
};
// Client code side of things
struct A
{
~A() { std::cout << "Destroyed an A\n"; }
};
struct B
{
~B() { std::cout << "Destroyed a B\n"; }
};
int main()
{
TypeErasedHolder holders[] = { A(), A(), B(), A() };
}
Как видите, TypeErasedHolder
может хранить объекты произвольного типа, и верно разрушают их. Важным моментом является то, что он не накладывает никаких ограничений на поддерживаемые типы(1): они не должны выводиться из общей базы, например.
(1) за исключением подвижности, конечно.