Использование минимальной неопределенности типов в C ++ - PullRequest
1 голос
/ 24 января 2012

В моей программе на C ++ есть структура данных, которая имеет некоторые атрибуты типа «Вектор» (определенные мной), а некоторые типа «double». В другом месте моего кода я бы очень хотел иметь возможность перебирать эту структуру данных и выполнять одни и те же арифметические операции с каждым значением. Операторы, которые мне понадобятся, определены для Vector, поэтому код буквально выглядит так же, как и для типа Vector и типа double.

Если это вообще возможно, я бы хотел избежать итерации по «векторным значениям», а затем отдельно итерировать по «двойным значениям».

Я понимаю, что это напрягает строгую типизацию C ++, но есть ли хороший способ сделать это?

EDIT:

Прямо сейчас я выполняю некоторые рутинные операции, подобные этой:

e.values.vel = k0[i].vel + k1[i].vel * c_1;
e.values.acc = k0[i].acc + k1[i].acc * c_1;
....

(e и k0 [i] - это один и тот же тип класса)

В настоящее время единственное, что мешает мне обобщить тип e, это то, что некоторые значения e могут быть векторами, а некоторые - двойными, и в идеале этот код будет иметь дело с различными объектами этого типа, которые могут иметь разные числа или виды ценностей. То, что я хочу, будет выглядеть так:

for (int j = 0; j < e.values.size(); j ++)
{
    e.values[j] = k0[i].values[j] + k1[i].values[j]
}

В идеале, я должен был бы быть итерируемым или предоставить какую-то следующую функцию, но для этого либо: он должен был бы хранить свои переменные в массиве, который может содержать только один известный тип, либо он предоставил бы Следующая функция, которая может возвращать только один известный тип.

Я пытаюсь найти способ, которым я могу абстрагировать эту концепцию, чтобы я мог перебирать что-то типа e, не зная типа каждого значения.

Ответы [ 3 ]

1 голос
/ 24 января 2012

Возможно, вы захотите рассмотреть Boost.Fusion .Это позволяет вам превращать ваш тип в последовательность времени компиляции, где вы можете использовать foreach, расширяющий время компиляции, для вызова соответствующего функтора для каждого элемента.

1 голос
/ 24 января 2012

Ваш векторный тип допускает несколько размерностей? Если это так, вы можете использовать 1-D Векторы в качестве оболочки для внутреннего типа double, а затем просто перебирать векторы.

class Vector {
public:
   Vector(int dimensions = 1);
   ...
   double& operator[](int index);
};

В качестве альтернативы, вы можете написать абстрактный класс Vector, а затем реализовать только те измерения, которые вам нужны: 1-, 2-, 3-d векторы являются общими.

class Vector {
public:
   ...
   Vector operator+(const Vector& rhs) const = 0;
   ...
};

class Vector1D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

class Vector2D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

class Vector3D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

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

Полагаю, я действительно хочу сказать, что вы должны просто интерпретировать двойные числа как одномерные векторы.

0 голосов
/ 24 января 2012

Вектор использует непрерывную память, очень похожую на массив, поэтому, предполагая, что ваши двойники находятся в массиве, вы можете выполнять итерацию по обоим одинаковым образом.Вы можете использовать шаблон функции для общей обработки их следующим образом:

template <typename T>
void DoOperationOnSequence(size_t maxIndex, const T& container) {
    for (int i = 0; i < maxIndex; ++i) {
        //Do something with container[i];
    }
}

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

PS: извините, если это не то, что вы искали, ваши вопросы немного сложны для понимания, поэтому я просто подумал, что сделаю удар :))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...