samedi 10 septembre 2022

Confused about Type Erasure in Hands-On Design Patterns with C++ by Fedor G. Pikus

In his book, Fedor G. Pikus talks about type erasure in C++. Specifically, he mentions the example of a smart pointer which has its own deleter whose type is "abstracted away".

This is the example he gives:

template <typename T>
class smartptr {

    struct deleter_base {
        virtual void apply(void*) = 0;
        virtual ~deleter_base() { }
    };

    template <typename Deleter>
    struct deleter : public deleter_base {
        deleter (Deleter d) : d_(d) { }
        virtual void apply(void* p) { d_(static_cast<T*>(p)); }
        Deleter d_;
    };

    public:
    template <typename Deleter>
        smartptr(T* p, Deleter d) : p_(p), d_(new deleter<Deleter>(d)) {}
    ~smartptr() { d_->apply(p_); delete d_; }
    T* operator->() { return p_; }
    const T* operator->() const { return p_; }

    private:
    T* p_;
    deleter_base* d_;
};

While I understand the implementation for the most part, there is one small thing I can't seem to figure out.

Why do the virtual apply methods of the deleter_base and deleter class use void* pointers and then static_cast to a pointer of type T* instead of just being of type T* to begin with?

As so:

...
    struct deleter_base {
        virtual void apply(T*) = 0;
        virtual ~deleter_base() { }
    };

    template <typename Deleter>
    struct deleter : public deleter_base {
        deleter (Deleter d) : d_(d) { }
        virtual void apply(T* p) { d_(p); }
        Deleter d_;
    };
...

Aucun commentaire:

Enregistrer un commentaire