Special C ++ Template Class for this Type List

I am writing some kind of sparse matrix implementation, in fact there are two different implementations: one for light types (i.e. sizeof(T) <= sizeof(int64) and one for heavy types.

Depending on sizeof(T) , I want to instantiate the corresponding class. At first, I tested a superclass that creates an implementation of HeavyType or LightType, but this requires both light and heavy inherit from the common virtual BaseClass, and the general call class uses this or that (not very clean) one in this way:

 template <class T> class Generic{ public: Generic(){ if (sizeof(T) > TRESHOLDVALUE) matrix_ = new HeavyType<T>(); else matrix_ = new LightType<T>(); } private: matrix_ * BaseClass<T>; }; 

This works, but it's not clean, and virtualization in BaseClass slows down execution ...

I would like to write only one class of templates and specialize it for several types, but I wonder: is it possible to specialize in a specific value of sizeof(T) (i.e. equivalent to if (sizeof(T) <= sizeof(int64)) )? or for an array of possible types ( template <> class Matrix<arrayOfPossibleTypes> )?

I would like to avoid re-writing the class for int , bool , uint_32 , int32 , etc types.

Does anyone have any ideas?

PS: As an alternative, I thought the pre-compiler macro selects the LightType or HeavyType class, but I think it's impossible to use sizeof() in the #if ancestor compiler.

+5
source share
3 answers

You are right that it is impossible to use sizeof in the preprocessor directive. And this is not necessary, you can specialize in sizeof(T) just fine. In fact, you can specialize in sizeof(T) <= sizeof(int64) :

 template <class T> class Generic{ private: MatrixType<T> matrix_; }; template <class T, bool Light = sizeof(T) <= sizeof(int64)> struct MatrixType; template <class T> struct MatrixType<T, true> { //light matrix }; template <class T> struct MatrixType<T, false> { //heavy matrix }; 
+10
source

One solution to this problem is std::enable_if (if you are using C ++ 11) or boost::enable_if (if you are using the old standard). You can add an additional template template to the template:

 template <class T, typename Enable = void> class Generic; template <class T> class Generic<T, typename boost::enable_if_c<sizeof(T) > TRESHOLDVALUE>::type> { // implementation for "heavy" class HeavyType<T> matrix_; }; template <class T> class Generic<T, typename boost::disable_if_c<sizeof(T) > TRESHOLDVALUE>::type> { // implementation for "light" class LightType<T> matrix_; }; 

It would be better if you really needed a different implementation for the โ€œlightโ€ and โ€œheavyโ€ ones. If all you have to do is change the type of the matrix_ member, and the rest of your implementation will remain the same, then you can use std::conditional (or its Boost equivalent, boost::mpl::if_c ).

+2
source

Using std::conditional you can do something like:

 template <class T> class Generic{ public: using MatrixType = typename std::conditional<(sizeof(T) > TRESHOLDVALUE), HeavyType<T>, LightType<T>>::type; Generic() {} private: MatrixType matrix_; }; 
+2
source

Source: https://habr.com/ru/post/1211541/


All Articles