Patrik Valkovič Patrik Valkovič - 17 days ago 5
C++ Question

Partial specialization for destructor

I am just working on my school homework, and I am interested if C++ could create specialized destructor for pointers. I know that this is not good practice, but because of performance, I want to do it this way. Also because I am curious about it. So lets say, that we have this class:

template<typename T,int(*comp)(const T& first, const T& second)>
class BinomialHeapLite
{
private:
class Node
{
Node* next;
T instance;
}
Node* top;
public:
~BinomialHeapLite();
}


Now I want destructor, that delete just node, if is T only type and delete also inner instance, if is T pointer..

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
//some code
delete this->top;
}

template<typename T, int(*comp)(const T* &first, const T* &second)>
BinomialHeapLite<T*,comp>::~BinomialHeapLite()
{
//some code
delete this->top->instance;
delete this->top;
}


But this give me "invalid use of incomplete type". I also want to use pure C++11, because I want to be independent to another libraries (also standards libraries), moreover that libraries are not permitted in out system.
Is something like this possible in pure C++?

Answer

You're giving your BinomialHeapLite class a responsibility that it shouldn't have: cleaning up instance if it's a heap-allocated pointer.

That burden should be on the user of your class: what if he is already calling delete in its own code? What if the object is supposed to be reused after your BinomialHeapLite is destroyed?

All your class should do is provide a generic container that manages its own memory. For that task, your should also use smart pointers (std::unique_ptr in this case):

template<typename T,int(*comp)(const T& first, const T& second)>
class BinomialHeapLite
{
private:
    class Node
    {
        std::unique_ptr<Node> next;
        T instance;
    }
    std::unique_ptr<Node> top;
}

You won't need an hand-written destructor then. Refer to the "rule of three/five/zero" for more information.


If you really want to implement your flawed/unconventional design, you could use a partially specialized helper struct that calls delete if its type is a pointer:

template <typename T>
struct dtor_helper
{
    static void do_it(T&&){}
};

template <typename T>
struct dtor_helper<T*>
{
    static void do_it(T* x){ delete x; }
};

template<typename T, int(*comp)(const T& first, const T& second)>
BinomialHeapLite<T,comp>::~BinomialHeapLite()
{
    //some code
    dtor_helper<T>::do_it(this->top->instance);
    delete this->top;
}

wandbox example