给定类型列表的 C++ 专用模板 class
C++ specialized template class for a given type list
我正在编写一种稀疏矩阵实现,实际上有 2 种不同的实现:一种用于轻型(即 sizeof(T) <= sizeof(int64)
,一种用于重型。
根据sizeof(T)
,我想实例化对应的class。我首先使用实例化 HeavyType 或 LightType 实现的 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>
)?
我想避免为 int
、bool
、uint_32
、int32
、[=21= 重写 class ] 类型。
有人知道吗?
PS:
或者,我想到了 select LightType 或 HeavyType 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_;
};
我正在编写一种稀疏矩阵实现,实际上有 2 种不同的实现:一种用于轻型(即 sizeof(T) <= sizeof(int64)
,一种用于重型。
根据sizeof(T)
,我想实例化对应的class。我首先使用实例化 HeavyType 或 LightType 实现的 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>
)?
我想避免为 int
、bool
、uint_32
、int32
、[=21= 重写 class ] 类型。
有人知道吗?
PS:
或者,我想到了 select LightType 或 HeavyType 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_;
};