f(*svec.begin()); //
//
f(&svec[0]); //
//
Фактически шаблон mem_fn можно считать string*, а другой — string&.
bind() для создания вызываемого объектаДля создания вызываемого объекта из функции-члена можно также использовать функцию bind() (см. раздел 10.3.4):
//
//
auto it = find_if(svec.begin(), svec.end(),
bind(&string::empty, _1));
Подобно шаблону function, при использовании функции bind() следует сделать явным обычно неявный параметр функции-члена, представляющий объект, с которым будет работать функция-член. Подобно шаблону mem_fn, первый аргумент вызываемого объекта, создаваемого функцией bind(), может быть либо указателем, либо ссылкой на тип string:
auto f = bind(&string::empty, _1);
f(*svec.begin()); //
//
f(&svec[0]); //
//
Упражнение 19.18. Напишите функцию, использующую алгоритм count_if() для подсчета количества пустых строк в заданном векторе.
Упражнение 19.19. Напишите функцию, получающую вектор vector и находящую первый элемент, средняя цена которого превосходит заданное значение.
19.5. Вложенные классы
Класс, определяемый в другом классе, называется QueryResult из приложения текстового запроса (см. раздел 12.3).
Имя вложенного класса видимо в области видимости содержащего его класса, но не вне ее. Имя вложенного класса не будет входить в конфликт с тем же именем, объявленным в другой области видимости.
Вложенный класс может содержать члены тех же видов, что и не вложенный класс. Подобно любому другому классу, вложенный класс контролирует доступ к своим членам при помощи спецификаторов доступа. Содержащий класс не имеет никаких специальных прав доступа к членам вложенного класса, а вложенный класс не имеет привилегий в доступе к членам содержащего его класса.
В содержащем классе вложенный класс представляет собой член, типом которого является класс. Подобно любому другому члену, содержащий класс задает уровень доступа к этому типу. Вложенный класс, определенный в разделе public содержащего класса, может быть использован везде. Вложенный класс, определенный в разделе protected, доступен только содержащему классу, его производным и дружественным классам. Вложенный класс, определенный в разделе private, доступен лишь для членов содержащего класса и классов, дружественных для него.
Класс TextQuery из раздела 12.3.2 определял сопутствующий класс QueryResult. Класс QueryResult жестко связан с классом TextQuery. Класс QueryResult имело бы смысл использовать и для других целей, а не только для результатов операции запроса к объекту класса TextQuery. Для отражения этой жесткой связи сделаем класс QueryResult членом класса TextQuery.
class TextQuery {
public:
class QueryResult; //
//
};
В первоначальный класс TextQuery необходимо внести только одно изменение — объявить о намерении определить класс QueryResult как вложенный. Поскольку класс QueryResult будет типом-членом (см. раздел 7.3.4), его следует объявить прежде, чем использовать. В частности, класс QueryResult следует объявить прежде, чем использовать его как тип возвращаемого значения функции-члена query(). Остальные члены первоначального класса неизменны.
В классе TextQuery класс QueryResult объявлен, но не определен. Подобно функциям-членам, вложенные классы следует объявить в классе, но определен он может быть в или вне класса.