I am writing a kind of sparse matrix implementation, in fact there are 2 distinct implementations: one for light types (ie 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)
(ie 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.
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
};
One solution to this problem is std::enable_if
(if you're using C++11) or boost::enable_if
(if you're using an older standard). You can add an extra dummy template parameter 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_;
};
This would be best if you actually need to have a different implementation for "light" versus "heavy." If all you're looking to do is change the type of the matrix_
member, and all the rest of your implementation stays the same, then you could use std::conditional
(or its Boost equivalent, boost::mpl::if_c
).
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_;
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.