<functional>
Функции
Эти функции устарели в C++11 и удалены в C++17:
bind1st
bind2nd
mem_fun
mem_fun_ref
ptr_fun
Эти функции устарели в C++17:
bind
Привязывает аргументы к вызываемому объекту.
template <class FT, class T1, class T2, ..., class TN>
unspecified bind(FT fn, T1 t1, T2 t2, ..., TN tN);
template <class RTy, class FT, class T1, class T2, ..., class TN>
unspecified bind(FT fn, T1 t1, T2 t2, ..., TN tN);
Параметры
FT
Тип объекта для вызова. Например, тип функции, объекта функции, указателя или указателя функции-члена.
RTy
Тип возвращаемого значения. При указании он будет возвращаемым типом привязанного вызова. В противном случае возвращаемый тип является возвращаемым типом FT
.
TN
Тип N-го аргумента вызова.
fn
Объект для вызова.
tN
N-й аргумент вызова.
Замечания
Типы FT, T1, T2, ..., TN
должны быть конструктором копирования и INVOKE(fn, t1, ..., tN)
должны быть допустимым выражением для некоторых значений w1, w2, ..., wN
.
Первая шаблонная функция возвращает пересылающую оболочку вызова g
со слабым типом результата. Результатом g(u1, u2, ..., uM)
является INVOKE(f, v1, v2, ..., vN,
invoke_result<FT cv (V1, V2, ..., VN)>::type)
, где cv
квалификаторы g
cv и значения и типы связанных аргументов v1, v2, ..., vN
определяются, как указано ниже. Его можно использовать для привязки к вызываемому объекту, чтобы создать вызываемый объект с адаптированным списком аргументов.
Вторая шаблонная функция возвращает пересылающую оболочку вызова g
с вложенным типом result_type
, который является синонимом для RTy
. Эффект g(u1, u2, ..., uM)
— INVOKE(f, v1, v2, ..., vN, RTy)
, где cv
— CV-квалификаторы g
, а значения и типы привязанных аргументов v1, v2, ..., vN
определяются следующим образом. Его можно использовать для привязки к вызываемому объекту, чтобы создать вызываемый объект с адаптированным списком аргументов и заданным типом возвращаемого значения.
Значения привязанных аргументов v1, v2, ..., vN
и их соответствующие типы V1, V2, ..., VN
зависят от типа соответствующего аргумента ti
типа Ti
в вызове функции bind
и CV-квалификаторах cv
оболочки вызова g
следующим образом:
Если ti
аргумент имеет ti.get()
тип reference_wrapper<T>
vi
, а его тип Vi
— T&
;
Если значение std::is_bind_expression<Ti>::value
аргумента true
vi
имеет значение ti(u1, u2, ..., uM)
, а его тип Vi
— result_of<Ti
cv
(U1&, U2&, ..., UN&>::type
;
Если значение j
не равно нулю аргумента std::is_placeholder<Ti>::value
uj
vi
, а его тип Vi
— ;Uj&
В противном случае аргумент vi
имеет ti
тип &
Vi
Ti
cv
.
Например, в случае функции f(int, int)
выражение bind(f, _1, 0)
возвращает пересылающую оболочку вызова cw
, чтобы cw(x)
вызывал f(x, 0)
. Выражение bind(f, 0, _1)
возвращает пересылающую оболочку вызова cw
, чтобы cw(x)
вызывал f(0, x)
.
Число аргументов в вызове bind
и аргументе fn
должно быть равно числу аргументов, которые могут передаваться вызываемому объекту fn
. Например, правильно, bind(cos, 1.0)
и bind(cos)
оба и bind(cos, _1, 0.0)
являются неверными.
Число аргументов в вызове функции, отправляемом в оболочку вызова, возвращаемом методом bind
, должен быть не меньше наивысшего нумерованного значения is_placeholder<PH>::value
для всех аргументов-местозаполнителей в вызове в bind
. Например, bind(cos, _2)(0.0, 1.0)
правильно (и возвращается cos(1.0)
) и bind(cos, _2)(0.0)
неправильно.
Пример
// std__functional__bind.cpp
// compile with: /EHsc
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std::placeholders;
void square(double x)
{
std::cout << x << "^2 == " << x * x << std::endl;
}
void product(double x, double y)
{
std::cout << x << "*" << y << " == " << x * y << std::endl;
}
int main()
{
double arg[] = { 1, 2, 3 };
std::for_each(&arg[0], arg + 3, square);
std::cout << std::endl;
std::for_each(&arg[0], arg + 3, std::bind(product, _1, 2));
std::cout << std::endl;
std::for_each(&arg[0], arg + 3, std::bind(square, _1));
return (0);
}
1^2 == 1
2^2 == 4
3^2 == 9
1*2 == 2
2*2 == 4
3*2 == 6
1^2 == 1
2^2 == 4
3^2 == 9
bind1st
Вспомогающая функция шаблона, которая создает адаптер для преобразования двоичного объекта функции в унарный объект функции. Он привязывает первый аргумент двоичной функции к указанному значению. Устарело в C++11, удалено в C++17.
template <class Operation, class Type>
binder1st <Operation> bind1st (const Operation& func, const Type& left);
Параметры
func
Объект бинарной функции, который необходимо преобразовать в объект унарной функции.
left
Значение, к которому необходимо привязать первый аргумент объекта бинарной функции.
Возвращаемое значение
Унарный объект функции, который приводит к привязке первого аргумента двоичного объекта функции к значению left
.
Замечания
Привязки функций — это своего рода адаптер функции. Так как они возвращают объекты функций, их можно использовать в определенных типах композиции функций для создания более сложных и мощных выражений.
Если func
объект типа Operation
и c
является константой, то bind1st( func, c )
он совпадает с binder1st
конструктором binder1st<Operation>(func, c)
классов и удобнее использовать его.
Пример
// functional_bind1st.cpp
// compile with: /EHsc
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
// Creation of a user-defined function object
// that inherits from the unary_function base class
class greaterthan5: unary_function<int, bool>
{
public:
result_type operator()(argument_type i)
{
return (result_type)(i > 5);
}
};
int main()
{
vector<int> v1;
vector<int>::iterator Iter;
int i;
for (i = 0; i <= 5; i++)
{
v1.push_back(5 * i);
}
cout << "The vector v1 = ( " ;
for (Iter = v1.begin(); Iter != v1.end(); Iter++)
cout << *Iter << " ";
cout << ")" << endl;
// Count the number of integers > 10 in the vector
vector<int>::iterator::difference_type result1a;
result1a = count_if(v1.begin(), v1.end(), bind1st(less<int>(), 10));
cout << "The number of elements in v1 greater than 10 is: "
<< result1a << "." << endl;
// Compare: counting the number of integers > 5 in the vector
// with a user defined function object
vector<int>::iterator::difference_type result1b;
result1b = count_if(v1.begin(), v1.end(), greaterthan5());
cout << "The number of elements in v1 greater than 5 is: "
<< result1b << "." << endl;
// Count the number of integers < 10 in the vector
vector<int>::iterator::difference_type result2;
result2 = count_if(v1.begin(), v1.end(), bind2nd(less<int>(), 10));
cout << "The number of elements in v1 less than 10 is: "
<< result2 << "." << endl;
}
The vector v1 = ( 0 5 10 15 20 25 )
The number of elements in v1 greater than 10 is: 3.
The number of elements in v1 greater than 5 is: 4.
The number of elements in v1 less than 10 is: 2.
bind2nd
Вспомогающая функция шаблона, которая создает адаптер для преобразования двоичного объекта функции в унарный объект функции. Он привязывает второй аргумент двоичной функции к указанному значению. Устарело в C++11, удалено в C++17.
template <class Operation, class Type>
binder2nd <Operation> bind2nd(const Operation& func, const Type& right);
Параметры
func
Объект бинарной функции, который необходимо преобразовать в объект унарной функции.
right
Значение, к которому необходимо привязать второй аргумент объекта бинарной функции.
Возвращаемое значение
Результат унарной функции при привязке второго аргумента двоичного объекта функции к right
.
Замечания
Привязки функций — это своего рода адаптер функции. Так как они возвращают объекты функций, их можно использовать в определенных типах композиции функций для создания более сложных и мощных выражений.
Если func
объект типа Operation
и является константой, то bind2nd(func, c)
он совпадает с c
binder2nd
конструктором binder2nd<Operation>(func, c)
классов и удобнее использовать его.
Пример
// functional_bind2nd.cpp
// compile with: /EHsc
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
// Creation of a user-defined function object
// that inherits from the unary_function base class
class greaterthan15: unary_function<int, bool>
{
public:
result_type operator()(argument_type i)
{
return (result_type)(i > 15);
}
};
int main()
{
vector<int> v1;
vector<int>::iterator Iter;
int i;
for (i = 0; i <= 5; i++)
{
v1.push_back(5 * i);
}
cout << "The vector v1 = ( ";
for (Iter = v1.begin(); Iter != v1.end(); Iter++)
cout << *Iter << " ";
cout << ")" << endl;
// Count the number of integers > 10 in the vector
vector<int>::iterator::difference_type result1a;
result1a = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 10));
cout << "The number of elements in v1 greater than 10 is: "
<< result1a << "." << endl;
// Compare counting the number of integers > 15 in the vector
// with a user-defined function object
vector<int>::iterator::difference_type result1b;
result1b = count_if(v1.begin(), v1.end(), greaterthan15());
cout << "The number of elements in v1 greater than 15 is: "
<< result1b << "." << endl;
// Count the number of integers < 10 in the vector
vector<int>::iterator::difference_type result2;
result2 = count_if(v1.begin(), v1.end(), bind1st(greater<int>(), 10));
cout << "The number of elements in v1 less than 10 is: "
<< result2 << "." << endl;
}
The vector v1 = ( 0 5 10 15 20 25 )
The number of elements in v1 greater than 10 is: 3.
The number of elements in v1 greater than 15 is: 2.
The number of elements in v1 less than 10 is: 2.
bit_and
Предопределенный объект функции, который выполняет побитовую операцию AND (двоичный operator&
) для его аргументов.
template <class Type = void>
struct bit_and : public binary_function<Type, Type, Type
{
Type operator()(
const Type& Left,
const Type& Right) const;
};
// specialized transparent functor for operator&
template <>
struct bit_and<void>
{
template <class T, class U>
auto operator()(T&& Left, U&& Right) const ->
decltype(std::forward<T>(Left) & std::forward<U>(Right));
};
Параметры
Type
, , T
U
Любой тип, поддерживающий operator&
, принимающий операнды указанного или выводимого типа.
Left
Левый операнд побитовой операции И. Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа T
.
Right
Правый операнд побитовой операции И. Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа U
.
Возвращаемое значение
Результат Left & Right
. Специализированный шаблон выполняет точную пересылку результата типа, возвращаемого operator&
.
Замечания
Функтор bit_and
ограничен целочисленными типами для основных типов данных или определяемыми пользователем типами, которые реализуют бинарную operator&
.
bit_not
Предопределенный объект функции, который выполняет побитовую операцию (NOT) (unary) для его аргумента operator~
. Добавлено в C++14.
template <class Type = void>
struct bit_not : public unary_function<Type, Type>
{
Type operator()(const Type& Right) const;
};
// specialized transparent functor for operator~
template <>
struct bit_not<void>
{
template <class Type>
auto operator()(Type&& Right) const -> decltype(~std::forward<Type>(Right));
};
Параметры
Type
Тип, поддерживающий унарный operator~
.
Right
Операнд побитовой операции дополнения. Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку значения lvalue или ссылочного аргумента rvalue выводимого типа Type
.
Возвращаемое значение
Результат ~ Right
. Специализированный шаблон выполняет точную пересылку результата типа, возвращаемого operator~
.
Замечания
Функтор bit_not
ограничен целочисленными типами для основных типов данных или определяемыми пользователем типами, которые реализуют бинарную operator~
.
bit_or
Предопределенный объект функции, который выполняет побитовую операцию OR (operator|
) в своих аргументах.
template <class Type = void>
struct bit_or : public binary_function<Type, Type, Type>
{
Type operator()(
const Type& Left,
const Type& Right) const;
};
// specialized transparent functor for operator|
template <>
struct bit_or<void>
{
template <class T, class U>
auto operator()(T&& Left, U&& Right) const
-> decltype(std::forward<T>(Left) | std::forward<U>(Right));
};
Параметры
Type
, , T
U
Любой тип, поддерживающий operator|
, принимающий операнды указанного или выводимого типа.
Left
Левый операнд побитовой операции ИЛИ. Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа T
.
Right
Правый операнд побитовой операции ИЛИ. Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа U
.
Возвращаемое значение
Результат Left | Right
. Специализированный шаблон выполняет точную пересылку результата типа, возвращаемого operator|
.
Замечания
Функтор bit_or
ограничен целочисленными типами для основных типов данных или определяемыми пользователем типами, которые реализуют operator|
.
bit_xor
Предопределенный объект функции, который выполняет побитовую операцию XOR (двоичную operator^
) по его аргументам.
template <class Type = void>
struct bit_xor : public binary_function<Type, Type, Type>
{
Type operator()(
const Type& Left,
const Type& Right) const;
};
// specialized transparent functor for operator^
template <>
struct bit_xor<void>
{
template <class T, class U>
auto operator()(T&& Left, U&& Right) const
-> decltype(std::forward<T>(Left) ^ std::forward<U>(Right));
};
Параметры
Type
, , T
U
Любой тип, поддерживающий operator^
, принимающий операнды указанного или выводимого типа.
Left
Левый операнд побитовой операции "исключающее ИЛИ". Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа T
.
Right
Правый операнд побитовой операции "исключающее ИЛИ". Неспециализированный шаблон принимает ссылочный аргумент lvalue типа Type
. Специализированный шаблон выполняет точную пересылку ссылочных аргументов lvalue и rvalue выводимого типа U
.
Возвращаемое значение
Результат Left ^ Right
. Специализированный шаблон выполняет точную пересылку результата типа, возвращаемого operator^
.
Замечания
Функтор bit_xor
ограничен целочисленными типами для основных типов данных или определяемыми пользователем типами, которые реализуют бинарную operator^
.
cref
Создает конструкцию reference_wrapper
из аргумента.
template <class Ty>
reference_wrapper<const Ty> cref(const Ty& arg);
template <class Ty>
reference_wrapper<const Ty> cref(const reference_wrapper<Ty>& arg);
Параметры
Ty
Тип аргумента, для которого создается оболочка.
arg
Аргумент для создания оболочки.
Замечания
Первая функция возвращает reference_wrapper<const Ty>(arg.get())
. Используется для создания оболочки для константной ссылки. Вторая функция возвращает reference_wrapper<const Ty>(arg)
. Используется для восстановления константной ссылки из ссылки в оболочке.
Пример
// std__functional__cref.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>
int neg(int val)
{
return (-val);
}
int main()
{
int i = 1;
std::cout << "i = " << i << std::endl;
std::cout << "cref(i) = " << std::cref(i) << std::endl;
std::cout << "cref(neg)(i) = "
<< std::cref(&neg)(i) << std::endl;
return (0);
}
i = 1
cref(i) = 1
cref(neg)(i) = -1
invoke
Вызывает любой вызываемый объект с заданными аргументами. Добавлено в C++17.
template <class Callable, class... Args>
invoke_result_t<Callable, Args...>
invoke(Callable&& fn, Args&&... args) noexcept(/* specification */);
Параметры
Callable
Тип объекта для вызова.
Args
Типы аргументов вызова.
fn
Объект для вызова.
args
Аргументы вызова.
specification
Спецификация noexcept
std::is_nothrow_invocable_v<Callable, Args>)
.
Замечания
Вызывает вызываемый объект fn
с помощью параметров args
. Фактически, INVOKE(std::forward<Callable>(fn), std::forward<Args>(args)...)
где псевдофукционная функция INVOKE(f, t1, t2, ..., tN)
означает одно из следующих вещей:
(t1.*f)(t2, ..., tN)
, еслиf
— это указатель на функцию-член классаT
, аt1
— это объект типаT
, ссылка на объект типаT
или ссылка на объект типа, производного отT
. То есть, когдаstd::is_base_of<T, std::decay_t<decltype(t1)>>::value
это верно.(t1.get().*f)(t2, ..., tN)
когдаf
является указателем на функцию-член классаT
иstd::decay_t<decltype(t1)>
является специализациейstd::reference_wrapper
.((*t1).*f)(t2, ..., tN)
еслиf
указатель на функцию-член классаT
иt1
не является одним из предыдущих типов.t1.*f
, если N == 1, аf
— это указатель на данные-член классаT
иt1
— это объект типаT
, ссылка на объект типаT
или ссылка на объект типа, производного отT
. То есть, когдаstd::is_base_of<T, std::decay_t<decltype(t1)>>::value
это верно.t1.get().*f
если N == 1 иf
является указателем на данные-члены классаT
иstd::decay_t<decltype(t1)>
является специализациейstd::reference_wrapper
.(*t1).*f
если N == 1 иf
является указателем на данные-члены классаT
иt1
не является одним из предыдущих типов.В остальных случаях —
f(t1, t2, ..., tN)
.
Сведения о типе результата вызываемого объекта см. в invoke_result. Предикаты для вызываемых типов см. в разделе is_invocable, is_invocable_r, is_nothrow_invocable, is_nothrow_invocable_r классов.
Пример
// functional_invoke.cpp
// compile using: cl /EHsc /std:c++17 functional_invoke.cpp
#include <functional>
#include <iostream>
struct Demo
{
int n_;
Demo(int const n) : n_{n} {}
void operator()( int const i, int const j ) const
{
std::cout << "Demo operator( " << i << ", "
<< j << " ) is " << i * j << "\n";
}
void difference( int const i ) const
{
std::cout << "Demo.difference( " << i << " ) is "
<< n_ - i << "\n";
}
};
void divisible_by_3(int const i)
{
std::cout << i << ( i % 3 == 0 ? " is" : " isn't" )
<< " divisible by 3.\n";
}
int main()
{
Demo d{ 42 };
Demo * pd{ &d };
auto pmf = &Demo::difference;
auto pmd = &Demo::n_;
// Invoke a function object, like calling d( 3, -7 )
std::invoke( d, 3, -7 );
// Invoke a member function, like calling
// d.difference( 29 ) or (d.*pmf)( 29 )
std::invoke( &Demo::difference, d, 29 );
std::invoke( pmf, pd, 13 );
// Invoke a data member, like access to d.n_ or d.*pmd
std::cout << "d.n_: " << std::invoke( &Demo::n_, d ) << "\n";
std::cout << "pd->n_: " << std::invoke( pmd, pd ) << "\n";
// Invoke a stand-alone (free) function
std::invoke( divisible_by_3, 42 );
// Invoke a lambda
auto divisible_by_7 = []( int const i )
{
std::cout << i << ( i % 7 == 0 ? " is" : " isn't" )
<< " divisible by 7.\n";
};
std::invoke( divisible_by_7, 42 );
}
Demo operator( 3, -7 ) is -21
Demo.difference( 29 ) is 13
Demo.difference( 13 ) is 29
d.n_: 42
pd->n_: 42
42 is divisible by 3.
42 is divisible by 7.
mem_fn
Создает простую оболочку вызова.
template <class RTy, class Ty>
unspecified mem_fn(RTy Ty::*pm);
Параметры
RTy
Тип возвращаемого значения функции в оболочке.
Ty
Тип указателя функции-члена.
Замечания
Функция шаблона возвращает простую оболочку cw
вызова с слабым типом результата, таким образом, что выражение cw(t, a2, ..., aN)
совпадает INVOKE(pm, t, a2, ..., aN)
с . Он не создает никаких исключений.
Возвращаемый оболочка вызова является производным от std::unary_function<cv Ty*, RTy>
(и определяет вложенный тип как синоним RTy
и вложенный тип result_type
argument_type
в качестве синонима) cv Ty*
только если тип Ty
является указателем на функцию-член с квалификатором cv-qualifiercv
, который не принимает аргументы.
Возвращаемый оболочка вызова является производным от std::binary_function<cv Ty*, T2, RTy>
(и определяет вложенный тип result_type
как синоним RTy
, вложенный тип в качестве синонима для , и вложенный тип second argument_type
в качестве синонима T2
) cv Ty*
только если тип first argument_type
Ty
является указателем на функцию-член с квалификатором cv-qualifiercv
, который принимает один аргумент типаT2
.
Пример
// std__functional__mem_fn.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>
class Funs
{
public:
void square(double x)
{
std::cout << x << "^2 == " << x * x << std::endl;
}
void product(double x, double y)
{
std::cout << x << "*" << y << " == " << x * y << std::endl;
}
};
int main()
{
Funs funs;
std::mem_fn(&Funs::square)(funs, 3.0);
std::mem_fn(&Funs::product)(funs, 3.0, 2.0);
return (0);
}
3^2 == 9
3*2 == 6
mem_fun
Вспомогательные функции шаблона, которые используются для создания адаптеров объекта-функции для функций-членов при инициализации с аргументами указателя. Не рекомендуется использовать c++11 для mem_fn
и bind
удалены в C++17.
template <class Result, class Type>
mem_fun_t<Result, Type> mem_fun (Result(Type::* pMem)());
template <class Result, class Type, class Arg>
mem_fun1_t<Result, Type, Arg> mem_fun(Result (Type::* pMem)(Arg));
template <class Result, class Type>
const_mem_fun_t<Result, Type> mem_fun(Result (Type::* pMem)() const);
template <class Result, class Type, class Arg>
const_mem_fun1_t<Result, Type, Arg> mem_fun(Result (Type::* pMem)(Arg) const);
Параметры
pMem
Указатель на функцию-член класса Type
для преобразования в объект функции.
Возвращаемое значение
const
Объект функции, отличный от const типа mem_fun_t
илиmem_fun1_t
.
Пример
// functional_mem_fun.cpp
// compile with: /EHsc
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
class StoreVals
{
int val;
public:
StoreVals() { val = 0; }
StoreVals(int j) { val = j; }
bool display() { cout << val << " "; return true; }
int squareval() { val *= val; return val; }
int lessconst(int k) {val -= k; return val; }
};
int main( )
{
vector<StoreVals *> v1;
StoreVals sv1(5);
v1.push_back(&sv1);
StoreVals sv2(10);
v1.push_back(&sv2);
StoreVals sv3(15);
v1.push_back(&sv3);
StoreVals sv4(20);
v1.push_back(&sv4);
StoreVals sv5(25);
v1.push_back(&sv5);
cout << "The original values stored are: " ;
for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
cout << endl;
// Use of mem_fun calling member function through a pointer
// square each value in the vector using squareval ()
for_each(v1.begin(), v1.end(), mem_fun<int, StoreVals>(&StoreVals::squareval));
cout << "The squared values are: " ;
for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
cout << endl;
// Use of mem_fun1 calling member function through a pointer
// subtract 5 from each value in the vector using lessconst ()
for_each(v1.begin(), v1.end(),
bind2nd (mem_fun1<int, StoreVals,int>(&StoreVals::lessconst), 5));
cout << "The squared values less 5 are: " ;
for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
cout << endl;
}
mem_fun_ref
Вспомогательные функции шаблона, которые используются для создания адаптеров объекта-функции для функций-членов при инициализации с помощью ссылочных аргументов. Устарело в C++11, удалено в C++17.
template <class Result, class Type>
mem_fun_ref_t<Result, Type> mem_fun_ref(Result (Type::* pMem)());
template <class Result, class Type, class Arg>
mem_fun1_ref_t<Result, Type, Arg> mem_fun_ref(Result (Type::* pMem)(Arg));
template <class Result, class Type>
const_mem_fun_ref_t<Result, Type> mem_fun_ref(Result Type::* pMem)() const);
template <class Result, class Type, class Arg>
const_mem_fun1_ref_t<Result, Type, Arg> mem_fun_ref(Result (T::* pMem)(Arg) const);
Параметры
pMem
Указатель на функцию-член класса Type
для преобразования в объект функции.
Возвращаемое значение
Объект функции const
или non_const
типа mem_fun_ref_t
или mem_fun1_ref_t
.
Пример
// functional_mem_fun_ref.cpp
// compile with: /EHsc
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
class NumVals
{
int val;
public:
NumVals ( ) { val = 0; }
NumVals ( int j ) { val = j; }
bool display ( ) { cout << val << " "; return true; }
bool isEven ( ) { return ( bool ) !( val %2 ); }
bool isPrime( )
{
if (val < 2) { return true; }
for (int i = 2; i <= val / i; ++i)
{
if (val % i == 0) { return false; }
}
return true;
}
};
int main( )
{
vector <NumVals> v1 ( 13 ), v2 ( 13 );
vector <NumVals>::iterator v1_Iter, v2_Iter;
int i, k;
for ( i = 0; i < 13; i++ ) v1 [ i ] = NumVals ( i+1 );
for ( k = 0; k < 13; k++ ) v2 [ k ] = NumVals ( k+1 );
cout << "The original values stored in v1 are: " ;
for_each( v1.begin( ), v1.end( ),
mem_fun_ref ( &NumVals::display ) );
cout << endl;
// Use of mem_fun_ref calling member function through a reference
// remove the primes in the vector using isPrime ( )
v1_Iter = remove_if ( v1.begin( ), v1.end( ),
mem_fun_ref ( &NumVals::isPrime ) );
cout << "With the primes removed, the remaining values in v1 are: " ;
for_each( v1.begin( ), v1_Iter,
mem_fun_ref ( &NumVals::display ) );
cout << endl;
cout << "The original values stored in v2 are: " ;
for_each( v2.begin( ), v2.end( ),
mem_fun_ref ( &NumVals::display ) );
cout << endl;
// Use of mem_fun_ref calling member function through a reference
// remove the even numbers in the vector v2 using isEven ( )
v2_Iter = remove_if ( v2.begin( ), v2.end( ),
mem_fun_ref ( &NumVals::isEven ) );
cout << "With the even numbers removed, the remaining values are: " ;
for_each( v2.begin( ), v2_Iter,
mem_fun_ref ( &NumVals::display ) );
cout << endl;
}
The original values stored in v1 are: 1 2 3 4 5 6 7 8 9 10 11 12 13
With the primes removed, the remaining values in v1 are: 4 6 8 9 10 12
The original values stored in v2 are: 1 2 3 4 5 6 7 8 9 10 11 12 13
With the even numbers removed, the remaining values are: 1 3 5 7 9 11 13
not1
Возвращает дополнение унарного предиката. Не рекомендуется использовать not_fn
в C++17.
template <class UnaryPredicate>
unary_negate<UnaryPredicate> not1(const UnaryPredicate& predicate);
Параметры
predicate
Унарный предикат, знак которого должен быть изменен.
Возвращаемое значение
Унарный предикат, который является отрицанием измененного унарного предиката.
Замечания
Если объект unary_negate
построен из унарного предиката predicate(x)
, он возвращается !predicate(x)
.
Пример
// functional_not1.cpp
// compile with: /EHsc
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
vector<int> v1;
vector<int>::iterator Iter;
int i;
for (i = 0; i <= 7; i++)
{
v1.push_back(5 * i);
}
cout << "The vector v1 = ( ";
for (Iter = v1.begin(); Iter != v1.end(); Iter++)
cout << *Iter << " ";
cout << ")" << endl;
vector<int>::iterator::difference_type result1;
// Count the elements greater than 10
result1 = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 10));
cout << "The number of elements in v1 greater than 10 is: "
<< result1 << "." << endl;
vector<int>::iterator::difference_type result2;
// Use the negator to count the elements less than or equal to 10
result2 = count_if(v1.begin(), v1.end(),
not1(bind2nd(greater<int>(), 10)));
cout << "The number of elements in v1 not greater than 10 is: "
<< result2 << "." << endl;
}
The vector v1 = ( 0 5 10 15 20 25 30 35 )
The number of elements in v1 greater than 10 is: 5.
The number of elements in v1 not greater than 10 is: 3.
not2
Возвращает дополнение бинарного предиката. Не рекомендуется использовать not_fn
в C++17.
template <class BinaryPredicate>
binary_negate<BinaryPredicate> not2(const BinaryPredicate& func);
Параметры
func
Бинарный предикат, знак которого должен быть изменен.
Возвращаемое значение
Бинарный предикат, который является отрицанием измененного бинарного предиката.
Замечания
Если объект binary_negate
построен из двоичного предиката binary_predicate(x, y)
, он возвращается !binary_predicate(x, y)
.
Пример
// functional_not2.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <iostream>
int main( )
{
using namespace std;
vector <int> v1;
vector <int>::iterator Iter1;
int i;
v1.push_back( 6262 );
v1.push_back( 6262 );
for ( i = 0 ; i < 5 ; i++ )
{
v1.push_back( rand( ) );
}
cout << "Original vector v1 = ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")" << endl;
// To sort in ascending order,
// use default binary predicate less<int>( )
sort( v1.begin( ), v1.end( ) );
cout << "Sorted vector v1 = ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")" << endl;
// To sort in descending order,
// use the binary_negate helper function not2
sort( v1.begin( ), v1.end( ), not2(less<int>( ) ) );
cout << "Resorted vector v1 = ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")" << endl;
}
Original vector v1 = ( 6262 6262 41 18467 6334 26500 19169 )
Sorted vector v1 = ( 41 6262 6262 6334 18467 19169 26500 )
Resorted vector v1 = ( 26500 19169 18467 6334 6262 6262 41 )
not_fn
Шаблон not_fn
функции принимает вызываемый объект и возвращает вызываемый объект. Когда возвращаемый вызываемый объект позже вызывается с некоторыми аргументами, он передает их исходному вызываемому объекту и логически отрицает результат. Он сохраняет поведение категории констант квалификации и значения вызываемого объекта. not_fn
является новым в C++17 и заменяет устаревшие std::not1
, и std::not2
std::unary_negate
, и std::binary_negate
.
template <class Callable>
/* unspecified */ not_fn(Callable&& func);
Параметры
func
Вызываемый объект, используемый для создания оболочки переадресации вызовов.
Замечания
Функция шаблона возвращает оболочку вызова, например return call_wrapper(std::forward<Callable>(func))
, на основе этого класса только для экспозиции:
class call_wrapper
{
using FD = decay_t<Callable>;
explicit call_wrapper(Callable&& func);
public:
call_wrapper(call_wrapper&&) = default;
call_wrapper(call_wrapper const&) = default;
template<class... Args>
auto operator()(Args&&...) & -> decltype(!declval<invoke_result_t<FD&(Args...)>>());
template<class... Args>
auto operator()(Args&&...) const& -> decltype(!declval<invoke_result_t<FD const&(Args...)>>());
template<class... Args>
auto operator()(Args&&...) && -> decltype(!declval<invoke_result_t<FD(Args...)>>());
template<class... Args>
auto operator()(Args&&...) const&& -> decltype(!declval<invoke_result_t<FD const(Args...)>>());
private:
FD fd;
};
Явный конструктор вызываемого объекта func
требует типа std::decay_t<Callable>
для удовлетворения требований MoveConstructible
и is_constructible_v<FD, Callable>
должен иметь значение true. Он инициализирует вызываемый объект fd
в оболочке и std::forward<Callable>(func)
создает исключение, возникающее при построении fd
.
Оболочка предоставляет операторы вызовов, отличающиеся от ссылочной категории lvalue или rvalue, и квалификации const, как показано ниже:
template<class... Args> auto operator()(Args&&... args) & -> decltype(!declval<invoke_result_t<FD&(Args...)>>());
template<class... Args> auto operator()(Args&&... args) const& -> decltype(!declval<invoke_result_t<FD const&(Args...)>>());
template<class... Args> auto operator()(Args&&... args) && -> decltype(!declval<invoke_result_t<FD(Args...)>>());
template<class... Args> auto operator()(Args&&... args) const&& -> decltype(!declval<invoke_result_t<FD const(Args...)>>());
Первые два совпадают return !std::invoke(fd, std::forward<Args>(args)...)
. Второе два совпадают return !std::invoke(std::move(fd), std::forward<Args>(args)...)
.
Пример
// functional_not_fn_.cpp
// compile with: /EHsc /std:c++17
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
int main()
{
std::vector<int> v1 = { 99, 6264, 41, 18467, 6334, 26500, 19169 };
auto divisible_by_3 = [](int i){ return i % 3 == 0; };
std::cout << "Vector v1 = ( " ;
for (const auto& item : v1)
{
std::cout << item << " ";
}
std::cout << ")" << std::endl;
// Count the number of vector elements divisible by 3.
int divisible =
std::count_if(v1.begin(), v1.end(), divisible_by_3);
std::cout << "Elements divisible by three: "
<< divisible << std::endl;
// Count the number of vector elements not divisible by 3.
int not_divisible =
std::count_if(v1.begin(), v1.end(), std::not_fn(divisible_by_3));
std::cout << "Elements not divisible by three: "
<< not_divisible << std::endl;
}
Vector v1 = ( 99 6264 41 18467 6334 26500 19169 )
Elements divisible by three: 2
Elements not divisible by three: 5
ptr_fun
Вспомогательные функции шаблона, которые используются для преобразования указателей на унарные и бинарные функции соответственно в унарные и бинарные адаптируемые функции. Устарело в C++11, удалено в C++17.
template <class Arg, class Result>
pointer_to_unary_function<Arg, Result, Result (*)(Arg)> ptr_fun(Result (*pfunc)(Arg));
template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1, Arg2, Result, Result (*)(Arg1, Arg2)> ptr_fun(Result (*pfunc)(Arg1, Arg2));
Параметры
pfunc
Указатель на унарную или бинарную функцию, который должен быть преобразован в адаптируемую функцию.
Возвращаемое значение
Первая функция шаблона возвращает унарную функцию pointer_to_unary_function<Arg
( Result
>(* ). pfunc
Вторая функция шаблона возвращает двоичные функции pointer_to_binary_function<Arg1
, Arg2
(Result
>* ). pfunc
Замечания
Указатель функции — это объект функции. Он может быть передан любому алгоритму, который ожидает функцию в качестве параметра, но она не адаптируется. Сведения о вложенных типах требуются для его использования с адаптером, например для привязки значения к нему или для его отмены. Преобразование указателей на унарные и бинарные функции с помощью вспомогательной функции ptr_fun
позволяет адаптерам функций работать с такими указателями.
Пример
// functional_ptr_fun.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>
#include <cstring>
#include <iostream>
int main( )
{
using namespace std;
vector <char*> v1;
vector <char*>::iterator Iter1, RIter;
v1.push_back ( "Open" );
v1.push_back ( "up" );
v1.push_back ( "the" );
v1.push_back ( "opalescent" );
v1.push_back ( "gates" );
cout << "Original sequence contains: " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; ++Iter1 )
cout << *Iter1 << " ";
cout << endl;
// To search the sequence for "opalescent"
// use a pointer_to_function conversion
RIter = find_if( v1.begin( ), v1.end( ),
not1 ( bind2nd (ptr_fun ( strcmp ), "opalescent" ) ) );
if ( RIter != v1.end( ) )
{
cout << "Found a match: "
<< *RIter << endl;
}
}
ref
Создает reference_wrapper
из аргумента.
template <class Ty>
reference_wrapper<Ty> ref(Ty& arg);
template <class Ty>
reference_wrapper<Ty> ref(reference_wrapper<Ty>& arg);
Возвращаемое значение
Ссылка на arg
, а именно reference_wrapper<Ty>(arg)
.
Пример
В приведенном ниже примере определяются две функции: одна из них привязана к строковой переменной, а другая — к ссылке строковой переменной, вычисленной с помощью вызова ref
. Когда значение переменной меняется, первая функция продолжает использовать старое значение, а вторая использует новое значение.
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>
using namespace std;
using namespace std;
using namespace std::placeholders;
bool shorter_than(const string& l, const string& r)
{
return l.size() < r.size();
}
int main()
{
vector<string> v_original;
v_original.push_back("tiger");
v_original.push_back("cat");
v_original.push_back("lion");
v_original.push_back("cougar");
copy(v_original.begin(), v_original.end(), ostream_iterator<string>(cout, " "));
cout << endl;
string s("meow");
function<bool (const string&)> f = bind(shorter_than, _1, s);
function<bool (const string&)> f_ref = bind(shorter_than, _1, ref(s));
vector<string> v;
// Remove elements that are shorter than s ("meow")
v = v_original;
v.erase(remove_if(v.begin(), v.end(), f), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
cout << endl;
// Now change the value of s.
// f_ref, which is bound to ref(s), will use the
// new value, while f is still bound to the old value.
s = "kitty";
// Remove elements that are shorter than "meow" (f is bound to old value of s)
v = v_original;
v.erase(remove_if(v.begin(), v.end(), f), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
cout << endl;
// Remove elements that are shorter than "kitty" (f_ref is bound to ref(s))
v = v_original;
v.erase(remove_if(v.begin(), v.end(), f_ref), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
cout << endl;
}
tiger cat lion cougar
tiger lion cougar
tiger lion cougar
tiger cougar
swap
Меняет местами два объекта function
.
template <class FT>
void swap(function<FT>& f1, function<FT>& f2);
Параметры
FT
Тип, управляемый объектами функции.
f1
Первый объект функции.
f2
Второй объект функции.
Замечания
Функция возвращает f1.swap(f2)
.
Пример
// std__functional__swap.cpp
// compile with: /EHsc
#include <functional>
#include <iostream>
int neg(int val)
{
return (-val);
}
int main()
{
std::function<int (int)> fn0(neg);
std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
std::cout << "val == " << fn0(3) << std::endl;
std::function<int (int)> fn1;
std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
std::cout << std::endl;
swap(fn0, fn1);
std::cout << std::boolalpha << "empty == " << !fn0 << std::endl;
std::cout << std::boolalpha << "empty == " << !fn1 << std::endl;
std::cout << "val == " << fn1(3) << std::endl;
return (0);
}
empty == false
val == -3
empty == true
empty == true
empty == false
val == -3