什么是C++中的类型擦除?

Ang*_*tis 11 c++ type-erasure

所以我正在读这篇关于类型擦除的文章.但该文章中的代码似乎部分不正确,例如:

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(); }
};
Run Code Online (Sandbox Code Playgroud)

其次是

void pullTheString()
{
    MyAnimal *animals[] = 
    {
        new AnimalWrapper(Cow()), /* oO , isn't template argument missing? */
        ....
    };
}
Run Code Online (Sandbox Code Playgroud)

这些错误使我不鼓励在文章中进一步阅读.

无论如何; 有没有人可以用简单的例子教C++中哪种类型的擦除?

我想了解它是如何std::function工作的,但无法理解它.

Rei*_*ica 15

这是一个非常简单的类型擦除实例:

// 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() };
}
Run Code Online (Sandbox Code Playgroud)

[实例]

如您所见,TypeErasedHolder可以存储任意类型的对象,并正确销毁它们.重要的是,它不会对所支持的类型施加任何限制(1):例如,它们不必从公共基础派生.


(1)当然,除了可移动之外.

  • (2)当然,除了可以销毁之外.另外,可移动的要求很容易修复:添加基于emplace的构造.`template <class T> struct emplace_as_t {}; template <class T> emplace_as_t <T> emplace_as = {};`然后添加ctor`template <class T,class ... Args> TypeErasedHolder(emplace_as_t <T>,Args && ... args)`等等但是那不是'基本类型擦除. (3认同)
  • @JonasWielicki保持示例的“非常简单”方面。使用转发引用还需要对TypeKeeper的模板参数使用std :: remove_reference,等等。 (2认同)