Александр Степанов - РУКОВОДСТВО ПО СТАНДАРТНОЙ БИБЛИОТЕКЕ ШАБЛОНОВ (STL)
transform(a.begin(), a.end(), b.begin(), a.begin(), plus‹double›());
Если мы хотим отрицать каждый элемент a, мы можем сделать это так:
transform(a.begin(), a.end(), a.begin(), negate‹double›());
Соответствующие функции вставят сложение и отрицание.
Чтобы позволить адаптерам и другим компонентам манипулировать функциональными объектами, которые используют один или два параметра, требуется, чтобы они соответственно обеспечили определение типов (typedefs) argument_type и result_type для функциональных объектов, которые используют один параметр, и first_argument_type, second_argument_type и result_type для функциональных объектов, которые используют два параметра.
Базовые классы (Base)
Следующие классы предоставляются, чтобы упростить определение типов (typedefs) параметров и результата:
template ‹class Arg, class Result›
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template ‹class Arg1, class Arg2, class Result›
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
Арифметические операции (Arithmetic operations)
Библиотека обеспечивает базовые классы функциональных объектов для всех арифметических операторов языка.
template ‹class T›
struct plus: binary_function‹T, T, T› {
Т operator()(const T& x, const T& y) const {return x + y;}
};
template ‹class T›
struct minus: binary_function‹T, T, T› {
Т operator()(const T& x, const T& y) const {return x - y;}
};
template ‹class T›
struct times: binary_function‹T, T, T› {
Т operator()(const T& x, const T& y) const (return x * y;}
};
template ‹class T›
struct divides: binary_function‹T, T, T› {
Т operator()(const T& x, const T& y) const {return x / y;}
};
template ‹class T›
struct modulus: binary_function‹T, T, T› {
Т operator()(const T& x, const T& y) const {return x % y;}
};
template ‹class T›
struct negate: unary_function‹T, T› {
Т operator()(const T& x) const {return -x;}
};
Сравнения (Comparisons)
Библиотека обеспечивает базовые классы функциональных объектов для всех операторов сравнения языка
template ‹class T›
struct equal_to: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x == y;}
};
template ‹class T›
struct not_equal_to: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x!= y;}
};
template ‹class T›
struct greater: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x › y;}
};
template ‹class T›
struct less: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x ‹ y;}
};
template ‹class T›
struct greater_equal: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x ›= y;}
};
template ‹class T›
struct less_equal: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x ‹= y;}
};
Логические операции (Logical operations)
template ‹class T›
struct logical_and: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x&& y;}
};
template ‹class T›
struct logical_or: binary_function‹T, T, bool› {
bool operator()(const T& x, const T& y) const {return x || y;}
};
template ‹class T›
struct logical_not: unary_function‹T, bool› {
bool operator()(const T& x) const {return!x;}
};
Распределители
Одна из общих проблем в мобильности - это способность инкапсулировать информацию относительно модели памяти. Эта информация включает типы указателей, тип их разности, тип размера объектов в этой модели памяти, также как её примитивы выделения и освобождения памяти.
STL принимается за эту проблему, обеспечивая стандартный набор требований для распределителей (allocators), являющихся объектами, которые инкапсулируют эту информацию. Все контейнеры в STL параметризованы в терминах распределителей. Это значительно упрощает задачу взаимодействия с многочисленными моделями памяти.
Требования распределителей (Allocator requirements)
В следующей таблице мы предполагаем, что X - класс распределителей для объектов типа T, a - значение X, n имеет тип X::size_type, p имеет тип X::pointer, r имеет тип X::reference и s имеет тип X::const_reference.
Все операции c распределителями, как ожидается, сводятся к постоянному времени.
Таблица 7. Требования распределителей
выражение возвращаемый тип утверждение/примечание состояние до/после X::value_type Т - X::reference леводопустимое значение T (lvalue of T) - X::const_reference const lvalue of T - X::pointer указатель на тип T результатом operator* для значений X::pointer является reference. X::const_pointer указатель на тип const T результат operator* для значений X::const_pointer ― const_reference; это - тот же самый тип указателя, как X::pointer, в частности, sizeof(X::const_pointer)==sizeof(X::pointer). X:: size_type беззнаковый целочисленный тип тип, который может представлять размер самого большого объекта в модели памяти. X::difference_type знаковый целочисленный тип тип, который может представлять разность между двумя любыми указателями в модели памяти. X a; - примечание: предполагается деструктор. a.address(r) указатель *(a.address(r))==r. a.const_address(s) const_pointer *(a.address(s))==s. a.allocate(n) X::pointer память распределяется для n объектов типа T, но объекты не создаются. allocate может вызывать соответствующее исключение. a.deallocate(p) результат не используется все объекты в области, указываемой p, должны быть уничтожены до этого запроса. construct(p, a) void после: *p==a. destroy(p) void значение, указываемое p, уничтожается. a.init_page_size() X::size_type возвращённое значение - оптимальное значение для начального размера буфера данного типа. Предполагается, что если k возвращено функцией init_page_size, t - время конструирования для T, и u - время, которое требуется для выполнения allocate(k), тогда k*t будет намного больше, чем u. a.max_size() X::size_type наибольшее положительное значение X::difference_typepointer относится к категории модифицируемых итераторов произвольного доступа, ссылающихся на T. const_pointer относится к категории постоянных итераторов произвольного доступа, ссылающихся на T. Имеется определённое преобразование из pointer в const_pointer.
Для любого шаблона распределителя Alloc имеется определение для типа void. У Alloc‹void› определены только конструктор, деструктор и Alloc‹void›::pointer. Преобразования определены из любого Alloc‹T›::pointer в Alloc‹void›::pointer и обратно, так что для любого p будет p == Alloc‹T›::pointer(Alloc‹void›::pointer(p)).
Распределитель по умолчанию (The default allocator)
template ‹class T›
class allocator {
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
allocator();
~allocator();
pointer address(reference x);
const_pointer const_address(const_reference x);
pointer allocate(size_type n);
void deallocate(pointer p);
size_type init_page_size();
size_type max_size();
};
class allocator‹void› {
public:
typedef void* pointer;
allocator();
~allocator();