我想建立一个节省空间的模块化算术类。这个想法是模量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值 vector 占用了所需空间的2倍。

我认为潜在的概念性问题是,不同模数的Mod在语法上属于同一类型,即使它们“应”为不同类型。例如,类似
m2 = m3;

应该“自然地”引发运行时错误(在我的版本中,它是“手动地”这样做:检查是内置在复制构造函数以及我实现的每个二进制运算符中的)。

那么,是否有一种方法可以实现某种动态类型,以便Mod对象的类型记住模数?我真的很感激任何想法如何解决这个问题。

对于我来说,这是一个反复出现的问题,具有各种数学结构(例如,在同一集合上存储许多排列,在同一组中的元素等等)

编辑:据我了解,
  • 模板是由类或文字参数化的类型。
  • 我想要的是:由const对象参数化的类型(在这种情况下为const num,对于组而言为const Group&const Group *const等)。

  • 这可能吗?

    最佳答案

    如果类需要在没有任何外部帮助的情况下知道M应该是什么,那么在零存储空间中很难做到这一点。您可能要做的最好的事情是存储指向共享M的指针,这取决于num的大小可能会好一些。但这不如免费。

    如果M是需要它的所有函数的传递值,则设计起来会更容易。然后,您可以做一些事情,例如创建一个对象池,这些对象都共享相同的M(有很多简单的方法可以设计此对象;例如map<num, vector<num> >),并且只为该池存储一次M。调用者将需要知道Mod对象来自哪个池,但是无论如何它可能都是已知的。

    很难孤立地完美地回答这个问题……了解更多有关调用代码的信息肯定会帮助您获得更好的答案。

    关于c++ - C++类设计:动态类型替代模板参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24371211/

    10-11 22:58
    查看更多