Funções <functional>
Essas funções são preteridas em C++11 e removidas em C++17:
bind1st
bind2nd
mem_fun
mem_fun_ref
ptr_fun
Essas funções foram preteridas no C++17:
bind
Associa argumentos a um objeto que pode ser chamado.
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);
Parâmetros
FT
O tipo do objeto a ser chamado. Por exemplo, o tipo da função, o objeto de função, o ponteiro/referência da função ou o ponteiro da função membro.
RTy
O tipo de retorno. Quando especificado, ele será o tipo de retorno da chamada associada. Caso contrário, o tipo de retorno será o tipo de retorno de FT
.
TN
O tipo do enésimo argumento de chamada.
fn
O objeto a ser chamado.
tN
O enésimo argumento de chamada.
Comentários
Os tipos FT, T1, T2, ..., TN
devem ser construíveis de cópias e INVOKE(fn, t1, ..., tN)
deve ser uma expressão válida para alguns valores de w1, w2, ..., wN
.
A primeira função de modelo retorna um wrapper de chamada de encaminhamento g
com um tipo de resultado fraco. O efeito de g(u1, u2, ..., uM)
é INVOKE(f, v1, v2, ..., vN,
invoke_result<FT cv (V1, V2, ..., VN)>::type)
, onde cv
são os qualificadores cv de g
e os valores e tipos dos argumentos v1, v2, ..., vN
associados são determinados conforme especificado abaixo. É possível usá-lo para associar argumentos a um objeto que pode ser chamado e criar um objeto que pode ser chamado com uma lista de argumentos personalizada.
A segunda função de modelo retorna um wrapper de chamada de encaminhamento g
com um tipo aninhado result_type
, que é sinônimo de RTy
. O efeito de g(u1, u2, ..., uM)
é INVOKE(f, v1, v2, ..., vN, RTy)
, em que cv
são os qualificadores cv de g
e os valores e tipos dos argumentos associados v1, v2, ..., vN
são determinados conforme especificado abaixo. É possível usá-lo para associar argumentos a um objeto que pode ser chamado e criar um objeto que pode ser chamado com uma lista de argumentos personalizada e um tipo de retorno especificado.
Os valores dos argumentos associados v1, v2, ..., vN
e seus tipos correspondentes V1, V2, ..., VN
dependem do tipo do argumento correspondente ti
de tipo Ti
na chamada para bind
e os qualificadores cv cv
do wrapper de chamada g
, da seguinte maneira:
Se ti
for do tipo reference_wrapper<T>
, o argumento vi
será ti.get()
e seu tipo Vi
será T&
;
Se o valor de std::is_bind_expression<Ti>::value
istrue
, o argumento vi
é ti(u1, u2, ..., uM)
e seu tipo Vi
é cv
result_of<Ti
(U1&, U2&, ..., UN&>::type
;
Se o valor j
de std::is_placeholder<Ti>::value
não for zero, o argumento vi
será uj
e seu tipo Vi
será Uj&
;
Caso contrário, o argumento vi
é e seu tipo Vi
é Ti
cv
&
.ti
Por exemplo, dada uma função f(int, int)
, a expressão bind(f, _1, 0)
retorna um wrapper de chamada de encaminhamento cw
, de forma que cw(x)
chama f(x, 0)
. A expressão bind(f, 0, _1)
retorna um wrapper de chamada encaminhamento cw
, de forma que cw(x)
chama f(0, x)
.
O número de argumentos em uma chamada para bind
e o argumento fn
devem ser iguais ao número de argumentos que podem ser passados para o objeto que pode ser chamado fn
. Por exemplo, bind(cos, 1.0)
está correto e bind(cos)
e bind(cos, _1, 0.0)
estão incorretos.
O número de argumentos na chamada de função para o wrapper de chamada retornado por bind
deve ser, pelo menos, tão grande quanto o maior valor numerado de is_placeholder<PH>::value
para todos os argumentos de espaço reservado na chamada para bind
. Por exemplo, bind(cos, _2)(0.0, 1.0)
está correto (e retorna cos(1.0)
) e bind(cos, _2)(0.0)
está incorreto.
Exemplo
// 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
Uma função de modelo auxiliar que cria um adaptador para converter um objeto de função binária em um objeto de função unária. Ele associa o primeiro argumento da função binária a um valor especificado. Preterido em C++11, removido em C++17.
template <class Operation, class Type>
binder1st <Operation> bind1st (const Operation& func, const Type& left);
Parâmetros
func
O objeto de função binária a ser convertido em um objeto de função unária.
left
O valor ao qual o primeiro argumento do objeto de função binária deve ser associado.
Valor de retorno
O objeto de função unária que resulta da associação do primeiro argumento do objeto de função binária ao valor left
.
Comentários
Os associadores de função são uma espécie de adaptador de função. Como retornam objetos de função, eles podem ser usados em determinados tipos de composição de função para construir expressões mais complicadas e avançadas.
Se func
for um objeto do tipo Operation
e c
for uma constante, bind1st( func, c )
será equivalente ao construtor de classe binder1st
binder1st<Operation>(func, c)
e será mais conveniente usá-lo.
Exemplo
// 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
Uma função de modelo auxiliar que cria um adaptador para converter um objeto de função binária em um objeto de função unária. Ele associa o segundo argumento da função binária a um valor especificado. Preterido em C++11, removido em C++17.
template <class Operation, class Type>
binder2nd <Operation> bind2nd(const Operation& func, const Type& right);
Parâmetros
func
O objeto de função binária a ser convertido em um objeto de função unária.
right
O valor ao qual o segundo argumento do objeto de função binária deve ser associado.
Valor de retorno
O objeto de função unária que resulta da associação do segundo argumento do objeto de função binária a right
.
Comentários
Os associadores de função são uma espécie de adaptador de função. Como retornam objetos de função, eles podem ser usados em determinados tipos de composição de função para construir expressões mais complicadas e avançadas.
Se func
for um objeto do tipo Operation
e c
for uma constante, bind2nd(func, c)
será equivalente ao construtor de classe binder2nd
binder2nd<Operation>(func, c)
e será mais conveniente usá-lo.
Exemplo
// 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
Um objeto de função predefinido que executa a operação bit a bit AND (operator&
binário) em seus argumentos.
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));
};
Parâmetros
Type
, T
, U
Qualquer tipo que dê suporte a um operator&
que usa operandos dos tipos especificados ou inferidos.
Left
O operando esquerdo da operação bit a bit AND. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido T
.
Right
O operando direito da operação bit a bit AND. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido U
.
Valor de retorno
O resultado de Left & Right
. O modelo especializado realiza o encaminhamento perfeito do resultado, que tem o tipo retornado por operator&
.
Comentários
O functor bit_and
é restrito a tipos integrais para os tipos de dados básicos ou a tipos definidos pelo usuário que implementam o operator&
binário.
bit_not
Um objeto de função predefinido que executa a operação complementar bit a bit (NOT) (operator~
unário) em seu argumento. Adicionado em 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));
};
Parâmetros
Type
Um tipo que dá suporte a um operator~
unário.
Right
O operando da operação complementar bit a bit. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito de um argumento de referência lvalue e rvalue do tipo inferido Type
.
Valor de retorno
O resultado de ~ Right
. O modelo especializado realiza o encaminhamento perfeito do resultado, que tem o tipo retornado por operator~
.
Comentários
O functor bit_not
é restrito a tipos integrais para os tipos de dados básicos ou a tipos definidos pelo usuário que implementam o operator~
binário.
bit_or
Um objeto de função predefinido que executa a operação bit a bit OR (operator|
) em seus argumentos.
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));
};
Parâmetros
Type
, T
, U
Qualquer tipo que dê suporte a um operator|
que usa operandos dos tipos especificados ou inferidos.
Left
O operando esquerdo da operação bit a bit OR. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido T
.
Right
O operando direito da operação bit a bit OR. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido U
.
Valor de retorno
O resultado de Left | Right
. O modelo especializado realiza o encaminhamento perfeito do resultado, que tem o tipo retornado por operator|
.
Comentários
O functor bit_or
é restrito a tipos integrais para os tipos de dados básicos ou a tipos definidos pelo usuário que implementam operator|
.
bit_xor
Um objeto de função predefinido que executa a operação bit a bit XOR (operator^
binário) em seus argumentos.
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));
};
Parâmetros
Type
, T
, U
Qualquer tipo que dê suporte a um operator^
que usa operandos dos tipos especificados ou inferidos.
Left
O operando esquerdo da operação bit a bit XOR. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido T
.
Right
O operando direito da operação bit a bit XOR. O modelo não especializado usa um argumento de referência lvalue do tipo Type
. O modelo especializado realiza o encaminhamento perfeito dos argumentos de referência lvalue e rvalue do tipo inferido U
.
Valor de retorno
O resultado de Left ^ Right
. O modelo especializado realiza o encaminhamento perfeito do resultado, que tem o tipo retornado por operator^
.
Comentários
O functor bit_xor
é restrito a tipos integrais para os tipos de dados básicos ou a tipos definidos pelo usuário que implementam o operator^
binário.
cref
Constrói uma constante reference_wrapper
de um argumento.
template <class Ty>
reference_wrapper<const Ty> cref(const Ty& arg);
template <class Ty>
reference_wrapper<const Ty> cref(const reference_wrapper<Ty>& arg);
Parâmetros
Ty
O tipo do argumento a ser encapsulado.
arg
O argumento a ser encapsulado.
Comentários
A primeira função retorna reference_wrapper<const Ty>(arg.get())
. Ela é usada para encapsular uma referência constante. A segunda função retorna reference_wrapper<const Ty>(arg)
. Ela é usada para encapsular novamente uma referência encapsulada como uma referência constante.
Exemplo
// 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
Invoca qualquer objeto que pode ser chamado com os argumentos fornecidos. Adicionado em C++17.
template <class Callable, class... Args>
invoke_result_t<Callable, Args...>
invoke(Callable&& fn, Args&&... args) noexcept(/* specification */);
Parâmetros
Callable
O tipo do objeto a ser chamado.
Args
Os tipos dos argumentos de chamada.
fn
O objeto a ser chamado.
args
Os argumentos de chamada.
specification
A especificação noexcept
std::is_nothrow_invocable_v<Callable, Args>)
.
Comentários
Invoca o objeto fn
que pode ser chamado usando os parâmetros args
. Efetivamente, INVOKE(std::forward<Callable>(fn), std::forward<Args>(args)...)
, em que a pseudo função INVOKE(f, t1, t2, ..., tN)
significa uma das seguintes possibilidades:
(t1.*f)(t2, ..., tN)
quandof
é um ponteiro para uma função membro da classeT
et1
é um objeto do tipoT
ou uma referência a um objeto do tipoT
ou uma referência a um objeto de um tipo derivado deT
. Ou seja, quandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
é verdadeiro.(t1.get().*f)(t2, ..., tN)
quandof
é um ponteiro para uma função de membro da classeT
estd::decay_t<decltype(t1)>
é uma especialização destd::reference_wrapper
.((*t1).*f)(t2, ..., tN)
quandof
é um ponteiro para uma função de membro da classeT
et1
não é um dos tipos anteriores.t1.*f
quando N == 1 ef
é um ponteiro para dados de membro de uma classeT
et1
é um objeto do tipoT
ou uma referência a um objeto do tipoT
ou uma referência a um objeto de um tipo derivado deT
. Ou seja, quandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
é verdadeiro.t1.get().*f
quando N == 1 ef
é um ponteiro para os dados de membro de uma classeT
estd::decay_t<decltype(t1)>
é uma especialização destd::reference_wrapper
.(*t1).*f
quando N == 1 ef
é um ponteiro para os dados de membro de uma classeT
et1
não é um dos tipos anteriores.f(t1, t2, ..., tN)
em todos os outros casos.
Para obter informações sobre o tipo de resultado de um objeto que pode ser chamado, confira invoke_result. Para predicados em tipos que podem ser chamados, confira as classes is_invocable, is_invocable_r, is_nothrow_invocable, is_nothrow_invocable_r.
Exemplo
// 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
Gera um wrapper de chamada simples.
template <class RTy, class Ty>
unspecified mem_fn(RTy Ty::*pm);
Parâmetros
RTy
O tipo de retorno da função encapsulada.
Ty
O tipo de ponteiro da função membro.
Comentários
A função de modelo retorna um wrapper de chamada simples cw
, com um tipo de resultado fraco, de modo que a expressão cw(t, a2, ..., aN)
é a mesma que INVOKE(pm, t, a2, ..., aN)
. Ela não gera nenhuma exceção.
O wrapper de chamada retornado é derivado de std::unary_function<cv Ty*, RTy>
(e definindo o tipo aninhado result_type
como sinônimo de RTy
e o tipo aninhado argument_type
como sinônimo de cv Ty*
) somente se o tipo Ty
for uma função de ponteiro para membro com um qualificador cv cv
que não utiliza argumentos.
O wrapper de chamada retornado é derivado de std::binary_function<cv Ty*, T2, RTy>
(e definindo o tipo aninhado result_type
como sinônimo de RTy
, o tipo aninhado first argument_type
como sinônimo de cv Ty*
e o tipo aninhado second argument_type
como sinônimo de T2
) somente se o tipo Ty
for uma função de ponteiro para membro com o qualificador cv cv
que não utiliza um argumento, do tipo T2
.
Exemplo
// 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
Funções de modelo auxiliares usadas para construir adaptadores de objeto de função para funções membro, quando inicializadas com argumentos de ponteiro. Preterido em C++11 para mem_fn
e bind
, e removido em 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);
Parâmetros
pMem
Um ponteiro para a função membro da classe Type
a ser convertida em um objeto de função.
Valor de retorno
Um objeto de função const
ou não constante do tipo mem_fun_t
ou mem_fun1_t
.
Exemplo
// 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
Funções de modelo auxiliares usadas para construir adaptadores de objeto de função para funções membro, quando inicializadas usando argumentos de referência. Preterido em C++11, removido em 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);
Parâmetros
pMem
Um ponteiro para a função membro da classe Type
a ser convertida em um objeto de função.
Valor de retorno
Um objeto de função const
ou non_const
do tipo mem_fun_ref_t
ou mem_fun1_ref_t
.
Exemplo
// 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
Retorna o complemento de um predicado unário. Preterido para not_fn
em C++17.
template <class UnaryPredicate>
unary_negate<UnaryPredicate> not1(const UnaryPredicate& predicate);
Parâmetros
predicate
O predicado unário a ser negado.
Valor de retorno
Um predicado unário que é a negação do predicado unário modificado.
Comentários
Se um unary_negate
for construído de um predicado unário predicate(x)
, ele retornará !predicate(x)
.
Exemplo
// 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
Retorna o complemento de um predicado binário. Preterido para not_fn
em C++17.
template <class BinaryPredicate>
binary_negate<BinaryPredicate> not2(const BinaryPredicate& func);
Parâmetros
func
O predicado binário a ser negado.
Valor de retorno
Um predicado binário que é a negação do predicado binário modificado.
Comentários
Se um binary_negate
for construído de um predicado binário binary_predicate(x, y)
, ele retornará !binary_predicate(x, y)
.
Exemplo
// 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
O modelo de função not_fn
usa um objeto que pode ser chamado e retorna um objeto que pode ser chamado. Quando o objeto que pode ser chamado retornado é invocado posteriormente com alguns argumentos, ele os passa para o objeto que pode ser chamado original e nega logicamente o resultado. Ele preserva o comportamento de categoria de valor e qualificação constante do objeto que pode ser chamado encapsulado. not_fn
é novo em C++17 e substitui os std::not1
, std::not2
, std::unary_negate
e std::binary_negate
preteridos.
template <class Callable>
/* unspecified */ not_fn(Callable&& func);
Parâmetros
func
Um objeto que pode ser chamado usado para construir o wrapper de chamada de encaminhamento.
Comentários
A função de modelo retorna um wrapper de chamada como return call_wrapper(std::forward<Callable>(func))
, com base nessa classe somente exposição:
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;
};
O construtor explícito no objeto func
que pode ser chamado requer o tipo std::decay_t<Callable>
para atender aos requisitos de MoveConstructible
, e is_constructible_v<FD, Callable>
deve ser verdadeiro. Ele inicializa o objeto fd
que pode ser chamado encapsulado, e std::forward<Callable>(func)
gera qualquer exceção gerada pela construção de fd
.
O wrapper expõe operadores de chamada diferenciados pela categoria de referência lvalue ou rvalue e pela qualificação constante, conforme mostrado aqui:
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...)>>());
Os dois primeiros são iguais a return !std::invoke(fd, std::forward<Args>(args)...)
. Os dois segundos são iguais a return !std::invoke(std::move(fd), std::forward<Args>(args)...)
.
Exemplo
// 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
Funções de modelo auxiliares usadas para converter ponteiros de funções unárias e binárias, respectivamente, em funções adaptáveis unárias e binárias. Preterido em C++11, removido em 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));
Parâmetros
pfunc
O ponteiro de função unária ou binária a ser convertido em uma função adaptável.
Valor de retorno
A primeira função de modelo retorna a função unária pointer_to_unary_function<Arg
, Result
>(* pfunc
).
A segunda função de modelo retorna a função binária pointer_to_binary_function<Arg1
, Arg2
, Result
>(* pfunc
).
Comentários
Um ponteiro de função é um objeto de função. Ele pode ser passado para qualquer algoritmo que espera uma função como um parâmetro, mas não é adaptável. Informações sobre seus tipos aninhados são necessárias para usá-lo com um adaptador, por exemplo, para associar um valor a ele ou para negá-lo. A conversão de ponteiros de funções unárias ou binárias pela função auxiliar ptr_fun
permite que os adaptadores de função funcionem com ponteiros de funções unárias ou binárias.
Exemplo
// 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
Constrói um reference_wrapper
de um argumento.
template <class Ty>
reference_wrapper<Ty> ref(Ty& arg);
template <class Ty>
reference_wrapper<Ty> ref(reference_wrapper<Ty>& arg);
Valor de retorno
Uma referência para arg
; especificamente, reference_wrapper<Ty>(arg)
.
Exemplo
O exemplo a seguir define duas funções: uma associada a uma variável de cadeia de caracteres e a outra associada a uma referência da variável de cadeia de caracteres calculada por uma chamada para ref
. Quando o valor da variável muda, a primeira função continua usando o valor antigo e a segunda função usa o novo valor.
#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
Troca dois objetos function
.
template <class FT>
void swap(function<FT>& f1, function<FT>& f2);
Parâmetros
FT
O tipo controlado pelos objetos de função.
f1
O primeiro objeto de função.
f2
O segundo objeto de função.
Comentários
A função retorna f1.swap(f2)
.
Exemplo
// 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