我想构建一个节省空间的模块化算术类。这个想法是模数 M 是一个在实例化期间固定的不可变属性,因此如果我们有一个具有相同 M 值的大型数组(std::vector 或其他容器),则 M 只需要存储一次。
如果 M 可以在编译时固定,这可以使用模板来完成:
template <typename num, num M> class Mod_template
{
private:
num V;
public:
Mod_template(num v=0)
{
if (M == 0)
V = v;
else
{
V = v % M;
if (V < 0)
V += M;
}
}
// ...
};
Mod_template<int, 5> m1(2); // 2 mod 5
但是,在我的应用程序中,我们应该能够表达 M 运行时。我所拥有的看起来像这样:
template <typename num> class Mod
{
private:
const num M;
num V;
public:
Mod(num m, num v=0): M(abs(m))
{
if (M == 0)
V = v;
else
{
V = v % M;
if (V < 0)
V += M;
}
}
// ...
};
Mod<int> m2(5, 2); // 2 mod 5
Mod<int> m3(3); // 0 mod 3
这可行,但是 mod M 值的大向量使用它需要的空间的 2 倍。
我认为潜在的概念问题是不同模数的 Mod 在语法上属于相同类型,即使它们“应该”是不同的类型。例如,像这样的语句
m2 = m3;
应该“自然”引发运行时错误(在我的版本中,它“手动”这样做:检查内置于复制构造函数以及我实现的每个二元运算符中)。
那么,有没有办法实现某种动态类型,以便 Mod 对象的类型记住模数?我真的很感激任何想法如何解决这个问题。
这对我来说是一个反复出现的问题,涉及各种数学结构(例如,在同一集合上存储许多排列、同一组的元素等)
编辑:据我所知,
模板是由类或文字参数化的类型。
我想要什么:由 const 对象参数化的类型(
const num
在这种情况下,const Group&
或const Group *const
用于组等)。
这可能吗?