Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
template_metaprogramming_ru.docx
Скачиваний:
12
Добавлен:
01.07.2025
Размер:
774 Кб
Скачать
☆

Синонимы функциональных алгоритмов:

Многие из алгоритмов создания последовательностей, чьи имена взяты из аналогичных алгоритмов STL, на самом деле возникли в функциональном программировании. Например, бинарная версии алгоритма transform в функциональных языках влется «map», с тремя аргументами – «zip_with», и copy_if также известна как «filter».

Reverse_ формы большинства алгоритмов производят те же элементы, но в обратном порядке, при этом элементы последовательности производенной алгоритмом unique и reverse_unique могут отличаться.

Например:

typedef mpl::equal_to<

mpl::shift_right<_1, mpl::int_<1>>,

mpl::shift_right<_2, mpl::int_<1>>

> same_except_last_bit; // predicate

typedef mpl::vector_c<int, 0,1,2,3,4,5> v;

// формирует новую последовательность для элементов v, предикат для которых дал true

typedef unique<

v, same_except_last_bit

>::type v024; // 0, 2, 4

typedef reverse_unique<

v, same_except_last_bit

>::type v531; // 5, 3, 1

Разбор:

int main()

{

cout << (0 >> 1) << endl; // 0

cout << (1 >> 1) << endl; // 0

cout << endl;

//----------------------------------

cout << (1 >> 1) << endl; // 0

cout << (2 >> 1) << endl; // 1

cout << endl;

//----------------------------------

cout << (2 >> 1) << endl; // 1

cout << (3 >> 1) << endl; // 1

cout << endl;

//----------------------------------

cout << (3 >> 1) << endl; // 1

cout << (4 >> 1) << endl; // 2

cout << endl;

//----------------------------------

cout << (4 >> 1) << endl; // 2

cout << (5 >> 1) << endl; // 2 (0101 >> 1 == 0010)

cout << endl;

//----------------------------------

// Так typedef unique<v, same_except_last_bit сравнивает:

// 0 и 1 -> предикат дает правду -> помещаем в новую последовательность 0

// 1 и 2 -> предикат дает ложь -> игнорируем выполнение для 1

// 2 и 3 -> предикат дает правду -> помещаем в новую последовательность 2

// ...

return 0;

}

Создание алгоритма

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

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

  • Это будет более эффективным и обобщенным решением. Не все последовательности поддерживают операцию pop_front с постоянной сложностью O(1), в то время как все итераторы поддерживают постоянную сложность O (1) приращения посредством next.

  • Аналогично iter_fold, решение, основанное на итераторах более обобщенное, чем работающее на элементах последовательности.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]