Си++/Стандартная библиотека: различия между версиями

Содержимое удалено Содержимое добавлено
м <source> -> <syntaxhighlight> (phab:T237267)
 
Строка 71:
на который ссылается обобщенный указатель, и <tt>free()</tt> — <tt>undo</tt> для <tt>construct()</tt>.
* std::allocator::pointer есть обычный указатель языка Си, методы реализованы примерно так:
<big><sourcesyntaxhighlight lang=cpp>
pointer std::allocator::allocate(size_t N)
{
Строка 92:
p->~T();
}
</sourcesyntaxhighlight></big>
* возможно писать свои реализации аллокаторов, при этом с ними будут работать все контейнеры, и общий внутренний код контейнеров, ответственный за "раздвижение" контейнера при вставке в середину и т.д.
 
Строка 115:
Правильный код для обхода контейнера:
 
<big><sourcesyntaxhighlight lang=cpp>
c.iterator itBegin = c.begin();
c.iterator itEnd = c.end();
Строка 122:
// на каждом шаге *it есть следующий объект внутри c
}
</sourcesyntaxhighlight></big>
 
Заметим, что это позволяет писать код, работающий с диапазонами итераторов, а не с контейнерами как
Строка 142:
 
Код этой функции очень прост (хотя и по началу непонятен, т.к. записан в библиотеке ужасным образом в плане эстетизма записи кода):
<big><sourcesyntaxhighlight lang=cpp>
namespace std {
template<class _II, class _Fn> inline
Строка 152:
}
} // end namespace std
</sourcesyntaxhighlight></big>
 
рассмотрим аргументы:
Строка 163:
 
Как видим, функция <tt>for_each</tt> всего-то-навсего для каждого элемента в контейнере вызывает функцию или оператор функтора. Также видно, что возвращаемое значение не играет роли. И все. Пример использования:
<big><sourcesyntaxhighlight lang=cpp>
//наш функтор
class FunctorToAdd
Строка 189:
cout<<mass[2]<<endl;
}
</sourcesyntaxhighlight></big>
 
В данной задаче (увеличение каждого элемента на 1) можно обойтись и простой функцией:
<big><sourcesyntaxhighlight lang=cpp>
void FuncToAdd(int& zn)
{
Строка 199:
std::for_each(mass.begin(),mass.end(),FuncToAdd);
</sourcesyntaxhighlight></big>
 
но в более сложных задачах может пригодится объект.
Строка 206:
 
Тут проще посмотреть на определение:
<big><sourcesyntaxhighlight lang=cpp>
namespace std {
template<class _II, class _OI, class _Uop> inline
Строка 216:
}
} // end namespace std
</sourcesyntaxhighlight></big>
 
<tt>transform</tt> помещает в новый контейнер (<tt>_X</tt> — итератор на его начало) значения, которые вернет наша функция (<tt>_U</tt>) или функтор от аргумента из исходного контейнера. Если указать источник равный приемнику, то будут соответственно изменены значения исходного контейнера. Пример использования:
<big><sourcesyntaxhighlight lang=cpp>
//нужно создать другую функцию, т.к. в transform используется возвращаемое значение
int FuncToAdd2(int zn)
Строка 228:
list<int> mass2;
std::transform(mass.begin(),mass.end(), back_inserter( mass2 ), FuncToAdd2 );
</sourcesyntaxhighlight></big>
 
<tt>back_inserter</tt> — функция, которая возвращает объект (<tt>back_insert_iterator</tt>),
Строка 239:
 
Подсчитывает количество элементов в указанном диапазоне контейнера, для которых выполняется унарный предикат (третий аргумент). К примеру, если у нас массив <tt>mass2=[0,1,2,3,4]</tt>, то:
<big><sourcesyntaxhighlight lang=cpp>
bool Count(int z)
{
Строка 247:
//вернет 2
cout<< count_if(mass2.begin(),mass2.end(),Count) <<endl;
</sourcesyntaxhighlight></big>
 
Ниже будет показан пример как этого же результата можно добится используя адаптеры вместо функции.
Строка 299:
 
В примере, где мы показывали работу с <tt>count_if</tt> не очень-то удобно создавать функцию (отвлекает как никак )). Поэтому рассмотрим следующий код, выполняющий ту же самую работу:
<big><sourcesyntaxhighlight lang=cpp>
cout<< count_if(mass2.begin(),mass2.end(), bind2nd(greater<int>(),2)) <<endl;
</sourcesyntaxhighlight></big>
 
Страшно? Ну ничего, сейчас всё объясню. <tt>greater</tt> — класс в котором перегружен оператор (),