|
Программирование >> Операторы преобразования типа
Вместо этого приходится использовать новые операторы преобразования типа (см, с. 35): va[std::slice(0.4,3)] = stat1c cast<std::valarray<double> >(va[std::slice(1.4.3)]} * static cast<std::valarray<double> >(va[std::sl1ce(2.4.3)]); Подойдет также старый механизм преобразования типа: va[std::slice(0.4.3)] - std;:valarray<double>(va[std::sl1ce(l.4.3)]) * std::valarray<double>(va[std::sl1ce(2.4.3)]): Ввод таких конструкций - занятие утомительное и чреватое ошибками. Что еще хуже, без хорошей оптимизации работа программы замедлится - при каждом преобразовании создается временный объект, который нужен исключительно для преобразования типа и ни для чего другого. Следующая шаблонная функция несколько упрощает работу с подмножествами: /* шаблон для преобразования подмножества элементов массива значений в массив значений template <class Т> inline std: :valarray<typenafTie Т: :value type> VA(const T& valarray subset) { return std::valarray<typena[ne T::value type>(valarray subset): При использовании этого шаблона предыдущий пример выглядит так: va[std::sl1ce(0.4.3)] = VA(va[std;:slice(1.4.3)]) * VACva[std;:slice(2.4.3)]): OK Однако проб.яема снижения быстродействия остается. При работе с элементами заданного типа также можно воспользоваться простым определением типа: typedef valarray<double> VAD: В этом случае запись выглядит так (при условии, что элементы va относятся к типу double): va[std::sl1ce(0.4.3)] = VAD(va[std::Sl1ce(l.4.3)]) * VAD(va[Std::Slice(2.4.3)]); OK Срезы Срез определяется набором индексов, который характеризуется тремя свойствами: О начальным индексом; О количеством элементов (размером); О расстоянием между элементами (шагом). Порядок передачи этих трех свойств точно соответствует порядку следования параметров конструктора класса slice. Например, следующее выражение определяет четыре элемента, начиная с индекса 2, находящихся на расстоянии 3 друг от друга: std::Sl1ce(2.4.3) Другими словами, выражение определяет такой набор индексов: 2 5 8 11 Шаг может быть отрицательным. Например, рассмотрим следующее выражение: std:;sl1ce(9.5,-2) Это выражение определяет такой набор индексов: 9 7 5 3 1 Чтобы определить подмножество элементов массива значений, достаточно передать срез в качестве аргумента оператора индексирования. Например, следующее выражение определяет подмножество массива va, содержащее элементы с индексами 2, 5, 8 и И: va[std::sl1ce(2.4.3)] Перед вызовом необходимо проверить правильность всех индексов. Если подмножество, заданное в виде среза, принадлежит константному массиву значений, то оно образует новый массив значений. Если массив значений не является константным, то подмножество предоставляет ссылочную семантику для работы с исходным массивом значений. Для этой цели определяется вспомогательный класс slice array: namespace std ( class slice: template <class T> class sl1ce array: template <class T> class valarray { public: Срез константного массива значений возвращает новый массив значений valarray<T> operator[] (slice) const; Срез неконстантного массива значений возвращает slice array sllce array<T> operator[] (slice); Для объектов slice array определены следующие операции: О присваивание одного значения всем элементам; О присваивание другого массива значений (или подмножества массива значений); О вызовы любых операций вычисляемого присваивания (с такими оператора-ми, как += и *=). Для остальных операций подмножество необходимо преобразовать в массив значений (см. с. 533). Учтите, что класс slice array проектировался исключительно как внутренний вспомогательный класс для работы со срезами, поэтому он должен оставаться невидимым для вненших пользователей. По этой причине все конструкторы и операторы присваивания класса slice array<> объявлены закрытыми. Например, представленная ниже команда присваивает 2 третьему, шестому, девятому и двенадцатому элементам массива значений va: va[std::Sl1ce(2.4.3)] = 2; Она эквивалентна следующему набору команд; va[2] = 2 va[5] = 2 va[B] = 2 vaCll] = 2; Другая команда возводит в квадрат элементы с индексами 2, 5, 8 и 11: va[std::slice(2.4.3)] *- std::valarray<double>(va[std::slice(2.4,3)]); Как упоминалось на с. 533, следующая запись является ошибочной: va[std::sl1ce(2.4.3)] *- va[std::sl1ce(2,4.3)]: ОШИБКА Но если воспользоваться шаблонной функцией VA() (см. с. 533), запись принимает следующий вид: va[std::sl1ce(2.4.3)] VA(va[std::Sl1ce(2.4.3)]); OK Передавая разные срезы одного массива значений, можно объединить подмножества и сохранить результат в другом подмножестве массива. Например, рассмотрим такую команду; va[std::slice(0.4.3)] = VA(va[std::slice(1.4.3)]) * VA(va[std::slice(1.4.3)]): Эта команда эквивалентна следующему набору команд: va[0] = va[l] * va[2]: va[3] = va[4] * va[5]; va[6] = va[7] * vaES]; va[9] = va[10] * va[ll];
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |