Что такое стирание типов в 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 7

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) за исключением того, что они движимы, конечно.