How to specialize a templated class at the class level

Viewed 38

Recently I was asked a question. I have the below templated class:

template<size_t SIZE>
class Cache
{
    // A lot of class methods omitted

    std::array<int, SIZE> _arr;
};

but someone might pass large a size and allocate on the stack, running out of stack memory. So you might suggest changing it to allocate on the heap:

template<size_t SIZE>
class Cache
{
    // A lot of class methods omitted

    std::unique_ptr<std::array<int, SIZE>> _arr;
};

but now those wanting a small array will pay the cost of indirection (i'm aware this is a very small cost but for the point of the question please accept).

Consequently it was hinted to me template specialization can allow some to choose the small std::array implementation and others to allocate their array on the heap.

I presume this specialization must be at the class level, because the std::array is a class member.

How is this class template specialization achieved without duplicating all the (omitted) class methods?

1 Answers

How is this class template specialization achieved without duplicating all the (omitted) class methods?

Abstract the thing you care about away into its own mixin class. For example:

template<size_t SIZE, bool> // default case, condition is false
class storage {
    std::unique_ptr<std::array<int, SIZE>> _arr;
protected:
    // constructor too...
    std::array<int, SIZE>& arr() { return *_arr; }
};

template<size_t SIZE> // special case, condition is true
class storage<SIZE, true> {
    std::array<int, SIZE> _arr;
protected:
    // constructor too...
    std::array<int, SIZE>& arr() { return _arr; }
};

Then simply have the cache use it as base, while checking SIZE for a threshold:

template<size_t SIZE>
class Cache : private storage<SIZE, (SIZE < THRESHOLD)>
{
    // A lot of class methods omitted
    // They now use this->arr();
};

You may also opt for composition instead. The specialization is pretty much the same in this case, but arr() is gonna need to be public so Cache may access it.

Related