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
объявлен, но не определен. Подобно функциям-членам, вложенные классы следует объявить в классе, но определен он может быть в или вне класса.