给定类型列表的C ++专用模板类

时间:2015-01-20 18:59:19

标签: c++ templates c-preprocessor

我正在编写一种稀疏矩阵实现,实际上有两种不同的实现:一种用于光类型(即sizeof(T) <= sizeof(int64),一种用于重型。

根据sizeof(T),我想实例化相应的类。我已先用该实例化类的超类测试的 HeavyType LightType 实施方式中,但是这需要轻和重以从共同的虚拟继承 BaseClass的,并且通用调用类以这种方式使用一个或另一个(不是很干净):

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

这很有效,但它不干净, BaseClass 中的虚拟化会降低执行速度......

我想只写一个模板类,和专门它为若干类型,但我不知道:的是它不可能性专门针对相当于sizeof(T) (即一个特定的值if (sizeof(T) <= sizeof(int64)))?或者是一组可能的类型(template <> class Matrix<arrayOfPossibleTypes>)?

我希望避免重写intbooluint_32int32etc类型的课程。

有没有人有想法?

PS: 或者,我想到一个预编译器宏来选择 LightType HeavyType 类,但我认为在sizeof()中使用#if是不可能的预编译器声明。

3 个答案:

答案 0 :(得分:10)

你是对的,因为在预处理程序指令中不可能使用sizeof。并且它不需要,你可以专注于sizeof(T)就好了。事实上,您可以专注于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
};

答案 1 :(得分:2)

此问题的一个解决方案是std::enable_if(如果您正在使用C ++ 11)或boost::enable_if(如果您使用旧版标准)。您可以向模板添加额外的虚拟模板参数:

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_;
};

如果你真的需要为&#34; light&#34;提供不同的实现,这将是最好的。与#34;重。&#34;如果你要做的只是更改matrix_成员的类型,并且所有其他实现保持不变,那么你可以使用std::conditional(或其Boost等效项,{ {1}})。

答案 2 :(得分:2)

使用std::conditional,您可以执行以下操作:

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