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?
CodePudding user response:
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.