Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КП - 2 часть - Лекция 4. STL.docx
Скачиваний:
12
Добавлен:
11.05.2015
Размер:
134.67 Кб
Скачать

3 Итераторы

Итераторы выступают в роли прослойки между различными типами контейнеров и алгоритмами. Алгоритмы работают в основном с итераторами. Передается итератор от какого элемента и итератор конечного элемента.

Итератор указывает на элемент. Он может ходить по коллекции вперед, назад, получать и получать, добавлять, менять элементы (некоторые типы итераторов в операциях более ограничены). У коллекций есть методы вида: дай итератор начала (begin()), дай итератор конца (end()). Итератор начала указывает на первый элемент. Итератор конца указывает за конечный элемент. Чтобы ходить вперед по итератору, нужно делать ++итератор. Чтобы получать значение по итератору, можно написать *итератор. Большинство итераторов сделаны в виде внутренних классов контейнеров и их экземпляры поэтому создаются как-то так: шаблонный_тип<шаблонные_аргументы>::iterator=коллекция.begin(). Поскольку такая форма слишком объемная, то используется

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

interface Iterator<TData>

{

TData GetElement();

boolMovNext();

voidReset();

}

4 Алгоритмы

Алгоритмы условно разделили на несколько групп. Примеры и идеи для примеров частично взяты с http://www.cplusplus.com/reference. Все алгоритмы связаны с работой с коллекциями. Аналог алгоритмов в таких языка какC# -Linq.

4.1 Не модифицируют коллекцию

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

#include "stdafx.h"

#include <iostream>

using namespace std;

void Print(int x)

{

cout << x << " ";

}

void PrintArray(void(*printElementPointer)(int), const int* array, int size)

{

for (int i = 0; i < size; i++)

{

printElementPointer(array[i]);

}

}

int _tmain(int argc, _TCHAR* argv[])

{

int data[] = { 13, 10, 666 };

PrintArray(Print, data, 3);

getchar();

}

Указатель на подпрограмму передается в какую-то подпрограмму, которая с помощью него нечто вытворяет. Например, подпрограмме печати нужно каждый раз как-то по-особому печатать. Теперь это представим в виде лямбда-выражения.

#include "stdafx.h"

#include <iostream>

using namespace std;

void PrintArray(void(*printElementPointer)(int), const int* array, int size)

{

for (int i = 0; i < size; i++)

{

printElementPointer(array[i]);

}

}

int _tmain(int argc, _TCHAR* argv[])

{

int data[] = { 13, 10, 666 };

PrintArray(

[](int x) {cout << x << " "; },

data,

3);

getchar();

}

Как видите, вместо адреса функции можно напрямую объявить саму функцию. Лямбда-выражение начинают с []. Затем идет тело функции. Неявно компилятор создаст подпрограмму из лямбда-выражения и подставит адрес функции.

4.1.1 All_of / any_of / none_of

Все элементы (как минимум один элемент / ни один из элементов) соответствуют условию.

Пример:

#include "stdafx.h"

#include <array>

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

std::array<int, 2> data = { 13, 55 };

if (std::all_of(

data.begin(),

data.end(),

[](int i){return i % 2; }))

{

std::cout << "All the elements are odd numbers.\n";

}

return 0;

}

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