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

C++ specialized template class for a given type list

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

根据sizeof(T),我想实例化对应的class。我首先使用实例化 HeavyTypeLightType 实现的 superclass 进行了测试,但这需要 light 和 heavy 继承来自一个普通的虚拟 BaseClass,而通用调用 class 以这种方式使用一个或另一个(不是很干净):

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 中的虚拟化减慢了执行速度...

我只想编写一个模板 class,并将其专门用于多种类型,但我想知道:是否可以针对 sizeof(T) 的特定值进行专门化(即相当于if (sizeof(T) <= sizeof(int64)))?或一组可能的类型 (template <> class Matrix<arrayOfPossibleTypes> )?

我想避免为 intbooluint_32int32、[=21= 重写 class ] 类型。

有人知道吗?

PS: 或者,我想到了 select LightTypeHeavyType class 的预编译器宏,但我认为这是不可能的在 #if 预编译器语句中使用 sizeof()

此问题的一个解决方案是 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_;
};

如果您确实需要对 "light" 和 "heavy." 进行不同的实现,那么这将是最好的 如果您只想更改 matrix_ 成员的类型,并且您的所有其余实现保持不变,那么您可以使用 std::conditional(或其等效的 Boost,boost::mpl::if_c)。

你说得对,不能在预处理器指令中使用 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
};

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