Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ specialized template class for a given type list

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

Depending on the sizeof(T), I want to instantiate the corresponding class. I have first tested with a superclass that instantiate the HeavyType or the LightType implementation, but this requires both light and heavy to inherit from a common virtual BaseClass, and the generic call class uses one or the other (not very clean) 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 is not clean, and the virtualization in BaseClass slows down the execution...

I would like to write only one template class, and specialize it for several types, but I wonder: is it possibile to specialize against a particular 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 the re-writing of the class for int, bool, uint_32, int32 , etc types.

Does anyone have an idea?

PS: Alternatively, I thought to a pre-compiler macro to select LightType or HeavyType class, but I think it's impossible to use sizeof() within a #if pre-compiler statement.

like image 352
Danduk82 Avatar asked Jan 20 '15 18:01

Danduk82


2 Answers

You're right that it's not possible to use sizeof in a preprocessor directive. And it's not needed, you can specialise on sizeof(T) just fine. In fact, you can specialise right on 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
};
like image 155
Angew is no longer proud of SO Avatar answered Nov 02 '22 23:11

Angew is no longer proud of SO


With std::conditional, you may 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_;
};
like image 41
Jarod42 Avatar answered Nov 03 '22 01:11

Jarod42