Дизайн класса C ++: динамическая типизация, альтернатива шаблонному аргументу?

Я хотел бы построить модульный арифметический класс с эффективным пространством. Идея состоит в том, что модуль M является неизменным атрибутом, который фиксируется во время создания экземпляра, поэтому, если у нас есть большой массив (std :: vector или другой контейнер) значений с тем же M, 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 раза больше места, чем нужно.

Я думаю, что основная концептуальная проблема заключается в том, что мод различных модулей синтаксически одного типа, даже если они «должны» быть разных типов. Например, заявление типа

m2 = m3;

должен вызывать ошибку времени выполнения «естественно» (в моей версии это происходит «вручную»: проверка встроена в конструктор копирования, а также в каждый бинарный оператор, который я реализую).

Итак, есть ли способ реализовать некоторую динамическую типизацию, чтобы тип объекта Mod запоминал модуль? Буду очень признателен за любую идею, как решить эту проблему.

Для меня это повторяющаяся проблема с различными математическими структурами (например, хранение множества перестановок в одном наборе, элементов одной группы и т. Д.)

РЕДАКТИРОВАТЬ: насколько я понимаю,

  • шаблоны — это типы, параметризованные классом или литералом.

  • что я хочу: тип, параметризованный const-объектом (const num в этом случае, const Group& или же const Group *const для групп и т. д.).

Это возможно?

3

Решение

Это будет трудно сделать в нулевом объеме памяти, если класс должен знать, что M должно быть без посторонней помощи. Вероятно, лучшее, что вы можете сделать, это сохранить указатель на общий Mчто может быть немного лучше, в зависимости от того, насколько большой num является. Но это не так хорошо, как бесплатно.

Это будет легче спроектировать, если M является переданным значением для всех функций, которые в нем нуждаются. Затем вы можете сделать такие вещи, как создать пул объектов, которые все имеют одинаковые M (Есть много простых способов создать это; например, map<num, vector<num> >) и только магазин M один раз для бассейна. Звонящий должен знать, какой пул Mod объект пришел, но это, вероятно, что-то, что он все равно знает.

Трудно ответить на этот вопрос совершенно изолированно … знание о вызывающем коде определенно поможет вам получить лучшие ответы.

1

Другие решения


По вопросам рекламы [email protected]