funciones<functional>
Estas funciones están en desuso en C++11 y se han quitado de C++17:
bind1st
bind2nd
mem_fun
mem_fun_ref
ptr_fun
Estas funciones están en desuso en C++17:
bind
Enlaza argumentos a un objeto al que se puede llamar.
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
El tipo del objeto al que se va a llamar. Por ejemplo, el tipo de la función, el objeto de función, el puntero o referencia de función, o el puntero de función miembro.
RTy
Tipo de valor devuelto. Cuando se especifica, será el tipo de valor devuelto de la llamada enlazada. De lo contrario, el tipo de valor devuelto es el tipo de valor devuelto de FT
.
TN
Tipo del enésimo argumento de llamada.
fn
El objeto al que se va a llamar.
tN
El enésimo argumento de llamada.
Comentarios
Los tipos FT, T1, T2, ..., TN
tienen que poder construirse mediante copia y INVOKE(fn, t1, ..., tN)
debe ser una expresión válida para algunos valores w1, w2, ..., wN
.
La primera función de plantilla devuelve un contenedor de llamadas de reenvío g
con un tipo de resultado débil. El efecto de g(u1, u2, ..., uM)
es INVOKE(f, v1, v2, ..., vN,
invoke_result<FT cv (V1, V2, ..., VN)>::type)
, donde cv
es los calificadores cv de g
y los valores y tipos de los argumentos enlazados v1, v2, ..., vN
se determinan como se especifica a continuación. Úselo para enlazar los argumentos con un objeto al que se puede llamar para crear un objeto al que se puede llamar con una lista de argumentos adaptada.
La segunda función de plantilla devuelve un contenedor de llamadas de reenvío g
con un tipo anidado result_type
que es un sinónimo de RTy
. El efecto de g(u1, u2, ..., uM)
es INVOKE(f, v1, v2, ..., vN, RTy)
, donde cv
son los calificadores cv de g
y los valores y tipos de los argumentos enlazados v1, v2, ..., vN
están determinados como se indica a continuación. Úselo para enlazar los argumentos con un objeto al que se puede llamar para crear un objeto al que se puede llamar con una lista de argumentos adaptada y con un tipo de valor devuelto especificado.
Los valores de los argumentos enlazados v1, v2, ..., vN
y sus tipos correspondientes V1, V2, ..., VN
dependen del tipo del argumento correspondiente ti
de tipo Ti
en la llamada a bind
y los calificadores cv cv
del contenedor de llamadas g
de la siguiente forma:
Si ti
es de tipo reference_wrapper<T>
, el argumento vi
es ti.get()
y su tipo Vi
es T&
.
Si el valor de std::is_bind_expression<Ti>::value
es true
el argumento vi
es ti(u1, u2, ..., uM)
y su tipo Vi
es result_of<Ti
cv
(U1&, U2&, ..., UN&>::type
;
Si el valor j
de std::is_placeholder<Ti>::value
no es cero, el argumento vi
es uj
y su tipo Vi
es Uj&
.
De lo contrario, el argumento vi
es y su tipo Vi
es Ti
cv
&
.ti
Por ejemplo, dada una función f(int, int)
, la expresión bind(f, _1, 0)
devuelve un contenedor de llamadas de reenvío cw
de modo que cw(x)
llama a f(x, 0)
. La expresión bind(f, 0, _1)
devuelve un contenedor de llamadas de reenvío cw
de modo que cw(x)
llama a f(0, x)
.
El número de argumentos en una llamada a bind
y el argumento fn
debe ser igual al número de argumentos que se puede pasar al objeto fn
al que se puede llamar. Por ejemplo, bind(cos, 1.0)
es correcto y bind(cos)
y bind(cos, _1, 0.0)
son incorrectos.
El número de argumentos de la llamada de función al contenedor de llamadas devuelto por bind
debe ser al menos tan grande como el valor numerado más alto de is_placeholder<PH>::value
para todos los argumentos de marcador de posición en la llamada a bind
. Por ejemplo, bind(cos, _2)(0.0, 1.0)
es correcto (y devuelve cos(1.0)
) y bind(cos, _2)(0.0)
es incorrecto.
Ejemplo
// 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
Función de plantilla del asistente que crea un adaptador para convertir un objeto de función binaria en un objeto de función unaria. Enlaza el primer argumento de la función binaria a un valor especificado. En desuso en C++11, quitada de C++17.
template <class Operation, class Type>
binder1st <Operation> bind1st (const Operation& func, const Type& left);
Parámetros
func
El objeto de función binaria que se va a convertir en un objeto de función unaria.
left
El valor al que se enlazará el primer argumento del objeto de función binaria.
Valor devuelto
El objeto de función unaria resultante de enlazar el primer argumento del objeto de función binaria con el valor left
.
Comentarios
Los enlazadores de función son un tipo de adaptador de función. Dado que devuelven objetos de función, se pueden usar en determinados tipos de composición de funciones para crear expresiones más complicadas y eficaces.
Si func
es un objeto de tipo Operation
y c
es una constante, bind1st( func, c )
es igual que el constructor de clase binder1st
binder1st<Operation>(func, c)
y es más conveniente usarlo.
Ejemplo
// 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
Función de plantilla del asistente que crea un adaptador para convertir un objeto de función binaria en un objeto de función unaria. Enlaza el segundo argumento de la función binaria a un valor especificado. En desuso en C++11, quitada de C++17.
template <class Operation, class Type>
binder2nd <Operation> bind2nd(const Operation& func, const Type& right);
Parámetros
func
El objeto de función binaria que se va a convertir en un objeto de función unaria.
right
El valor al que se enlazará el segundo argumento del objeto de función binaria.
Valor devuelto
El objeto de función unaria resultante de enlazar el segundo argumento del objeto de función binaria con right
.
Comentarios
Los enlazadores de función son un tipo de adaptador de función. Dado que devuelven objetos de función, se pueden usar en determinados tipos de composición de funciones para crear expresiones más complicadas y eficaces.
Si func
es un objeto de tipo Operation
y c
es una constante, bind2nd(func, c)
es igual que el constructor de clase binder2nd
binder2nd<Operation>(func, c)
y es más conveniente usarlo.
Ejemplo
// 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
Objeto de función predefinido que realiza la operación AND bit a bit (operator&
binario) sobre sus 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
Cualquier tipo que admite un operator&
que toma operandos de los tipos especificados o deducidos.
Left
Operando izquierdo de la operación AND bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido T
.
Right
Operando derecho de la operación AND bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido U
.
Valor devuelto
Resultado de Left & Right
. La plantilla especializada realiza el reenvío directo del resultado, que tiene el tipo devuelto por operator&
.
Comentarios
El functor de bit_and
está limitado a tipos enteros para los tipos de datos básicos, o a tipos definidos por el usuario que implementan el operator&
binario.
bit_not
Objeto de función predefinido que realiza la operación de complemento bit a bit (NOT) (operator~
unario) sobre su argumento. Se incluyó en 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
Tipo que admite un operator~
unario.
Right
Operando de la operación de complemento bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de un argumento de referencia de valor L o valor R del tipo deducido Type
.
Valor devuelto
Resultado de ~ Right
. La plantilla especializada realiza el reenvío directo del resultado, que tiene el tipo devuelto por operator~
.
Comentarios
El functor de bit_not
está limitado a tipos enteros para los tipos de datos básicos, o a tipos definidos por el usuario que implementan el operator~
binario.
bit_or
Objeto de función predefinido que realiza una operación OR bit a bit (operator|
) sobre sus 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
Cualquier tipo que admite un operator|
que toma operandos de los tipos especificados o deducidos.
Left
Operando izquierdo de la operación OR bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido T
.
Right
Operando derecho de la operación OR bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido U
.
Valor devuelto
Resultado de Left | Right
. La plantilla especializada realiza el reenvío directo del resultado, que tiene el tipo devuelto por operator|
.
Comentarios
El functor de bit_or
está limitado a tipos enteros para los tipos de datos básicos, o a tipos definidos por el usuario que implementan el operator|
.
bit_xor
Objeto de función predefinido que realiza la operación XOR bit a bit (operator^
binario) sobre sus 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
Cualquier tipo que admite un operator^
que toma operandos de los tipos especificados o deducidos.
Left
Operando izquierdo de la operación XOR bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido T
.
Right
Operando derecho de la operación XOR bit a bit. La plantilla no especializada toma un argumento de referencia de valor L de tipo Type
. La plantilla especializada realiza el reenvío directo de los argumentos de referencia de valor L y valor R del tipo deducido U
.
Valor devuelto
Resultado de Left ^ Right
. La plantilla especializada realiza el reenvío directo del resultado, que tiene el tipo devuelto por operator^
.
Comentarios
El functor de bit_xor
está limitado a tipos enteros para los tipos de datos básicos, o a tipos definidos por el usuario que implementan el operator^
binario.
cref
Construye un reference_wrapper
const a partir de un 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
El tipo del argumento que se encapsulará.
arg
El argumento que se encapsulará.
Comentarios
La primera función devuelve reference_wrapper<const Ty>(arg.get())
. Úsela para encapsular una referencia const. La segunda función devuelve reference_wrapper<const Ty>(arg)
. Úsela para volver a encapsular una referencia encapsulada como referencia const.
Ejemplo
// 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 cualquier objeto invocable con los argumentos especificados. Se incluyó en C++17.
template <class Callable, class... Args>
invoke_result_t<Callable, Args...>
invoke(Callable&& fn, Args&&... args) noexcept(/* specification */);
Parámetros
Callable
El tipo del objeto al que se va a llamar.
Args
Los tipos de los argumentos de llamada.
fn
El objeto al que se va a llamar.
args
Argumentos de llamada.
specification
La especificación noexcept
std::is_nothrow_invocable_v<Callable, Args>)
.
Comentarios
Invoca el objeto invocable fn
mediante los parámetros args
. En la práctica, INVOKE(std::forward<Callable>(fn), std::forward<Args>(args)...)
, donde la pseudofunción INVOKE(f, t1, t2, ..., tN)
significa una de las cosas siguientes:
(t1.*f)(t2, ..., tN)
cuandof
es un puntero a una función miembro de claseT
yt1
es un objeto de tipoT
, una referencia a un objeto de tipoT
o una referencia a un objeto de un tipo derivado deT
. Es decir, cuandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
es true.(t1.get().*f)(t2, ..., tN)
cuandof
es un puntero a una función miembro de la claseT
ystd::decay_t<decltype(t1)>
es una especialización destd::reference_wrapper
.((*t1).*f)(t2, ..., tN)
cuandof
es un puntero a una función miembro de claseT
yt1
no es uno de los tipos anteriores.t1.*f
cuando N == 1 yf
es un puntero a datos de miembro de una claseT
yt1
es un objeto de tipoT
, una referencia a un objeto de tipoT
o una referencia a un objeto de un tipo derivado deT
. Es decir, cuandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
es true.t1.get().*f
cuando N == 1 yf
es un puntero a datos de miembro de la claseT
ystd::decay_t<decltype(t1)>
es una especialización destd::reference_wrapper
.(*t1).*f
cuando N == 1 yf
es un puntero a datos de miembro de una claseT
yt1
no es uno de los tipos anteriores.f(t1, t2, ..., tN)
en todos los demás casos.
Para obtener información sobre el tipo de resultado de un objeto invocable, consulte invoke_result. Para conocer los predicados de tipos invocables, consulte las clases is_invocable, is_invocable_r, is_nothrow_invocable, is_nothrow_invocable_r.
Ejemplo
// 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
Genera un contenedor de llamadas simple.
template <class RTy, class Ty>
unspecified mem_fn(RTy Ty::*pm);
Parámetros
RTy
Tipo de valor devuelto de la función encapsulada.
Ty
El tipo del puntero de función miembro.
Comentarios
La función de plantilla devuelve un contenedor simple de llamadas cw
, con un tipo de resultado débil, de modo que la expresión cw(t, a2, ..., aN)
es igual que INVOKE(pm, t, a2, ..., aN)
. No produce ninguna excepción.
El contenedor de llamadas devuelto deriva de std::unary_function<cv Ty*, RTy>
(y el tipo anidado result_type
se define como sinónimo de RTy
y el tipo anidado argument_type
como sinónimo de cv Ty*
) solo si el tipo Ty
es un puntero a una función miembro con el calificador cv cv
que no toma ningún argumento.
El contenedor de llamadas devuelto deriva de std::binary_function<cv Ty*, T2, RTy>
(y el tipo anidado result_type
se define como sinónimo de RTy
, el tipo anidado first argument_type
como sinónimo de cv Ty*
y el tipo anidado second argument_type
como sinónimo de T2
) solo si el tipo Ty
es un puntero a una función miembro con el calificador cv cv
que no toma ningún argumento, de tipo T2
.
Ejemplo
// 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
Funciones de plantilla del asistente utilizadas para construir adaptadores de objeto de función para las funciones miembro cuando se inicializan con argumentos de puntero. En desuso en C++11 para mem_fn
y bind
, y se ha quitado de 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
Un puntero a la función miembro de clase Type
que se convertirá en un objeto de función.
Valor devuelto
Un objeto de función const
o no constante de tipo mem_fun_t
o mem_fun1_t
.
Ejemplo
// 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
Las funciones de plantilla del asistente usadas para crear adaptadores de objeto de función para las funciones miembro cuando se inicializan con argumentos de referencia. En desuso en C++11, quitada de 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
Un puntero a la función miembro de clase Type
que se convertirá en un objeto de función.
Valor devuelto
Un objeto de función const
o non_const
de tipo mem_fun_ref_t
o mem_fun1_ref_t
.
Ejemplo
// 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
Devuelve el complemento de un predicado unario. En desuso para not_fn
en C++17.
template <class UnaryPredicate>
unary_negate<UnaryPredicate> not1(const UnaryPredicate& predicate);
Parámetros
predicate
Predicado unario que se va a negar.
Valor devuelto
Un predicado unario que es la negación del predicado unario modificado.
Comentarios
Si unary_negate
se construye a partir de un predicado unario predicate(x)
, devuelve !predicate(x)
.
Ejemplo
// 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
Devuelve el complemento de un predicado binario. En desuso para not_fn
en C++17.
template <class BinaryPredicate>
binary_negate<BinaryPredicate> not2(const BinaryPredicate& func);
Parámetros
func
Predicado binario que se va a negar.
Valor devuelto
Un predicado binario que es la negación del predicado binario modificado.
Comentarios
Si binary_negate
se construye a partir de un predicado binario binary_predicate(x, y)
, devuelve !binary_predicate(x, y)
.
Ejemplo
// 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
La plantilla de función not_fn
toma un objeto invocable y devuelve un objeto invocable. Cuando el objeto invocable devuelto se invoca posteriormente con algunos argumentos, los pasa al objeto invocable original y niega lógicamente el resultado. Conserva el comportamiento de la categoría de valor y la calificación const del objeto invocable encapsulado. not_fn
es una novedad de C++17 y reemplaza a los elementos std::not1
, std::not2
, std::unary_negate
y std::binary_negate
en desuso.
template <class Callable>
/* unspecified */ not_fn(Callable&& func);
Parámetros
func
Objeto invocable que se usa para construir el contenedor de llamadas de reenvío.
Comentarios
La función de plantilla devuelve un contenedor de llamadas como return call_wrapper(std::forward<Callable>(func))
, basado en esta clase de solo exposición:
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;
};
El constructor explícito del objeto invocable func
requiere que el tipo std::decay_t<Callable>
cumpla los requisitos de MoveConstructible
, y is_constructible_v<FD, Callable>
debe ser true. Inicializa el objeto invocable encapsulado fd
desde std::forward<Callable>(func)
y produce cualquier excepción generada por la construcción de fd
.
El contenedor expone operadores de llamada distinguidos mediante la categoría de referencia lvalue o rvalue y la calificación const, como se muestra aquí:
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...)>>());
Los dos primeros son iguales que return !std::invoke(fd, std::forward<Args>(args)...)
. Los dos segundos son iguales que return !std::invoke(std::move(fd), std::forward<Args>(args)...)
.
Ejemplo
// 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
Funciones de plantilla del asistente usadas para convertir punteros de funciones unarias y binarias, respectivamente, en funciones unarias y binarias adaptables. En desuso en C++11, quitada de 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
El puntero de función unaria o binaria que se convertirá en una función adaptable.
Valor devuelto
La primera función de plantilla devuelve la función unaria pointer_to_unary_function<Arg
, Result
>(* pfunc
).
La segunda función de plantilla devuelve la función binaria pointer_to_binary_function<Arg1
, Arg2
, Result
>(* pfunc
).
Comentarios
Un puntero de función es un objeto de función. Se puede pasar a cualquier algoritmo que espera una función como parámetro, pero no es adaptable. Se requiere información sobre sus tipos anidados para usarla con un adaptador, por ejemplo, para enlazar un valor a él o para negarlo. La conversión de punteros de función unarios y binarios mediante la función del asistente ptr_fun
permite a los adaptadores de función trabajar con punteros de función unarios y binarios.
Ejemplo
// 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
Construye un reference_wrapper
a partir de un argumento.
template <class Ty>
reference_wrapper<Ty> ref(Ty& arg);
template <class Ty>
reference_wrapper<Ty> ref(reference_wrapper<Ty>& arg);
Valor devuelto
Referencia a arg
, específicamente, reference_wrapper<Ty>(arg)
.
Ejemplo
El siguiente ejemplo define dos funciones: una enlazada a una variable de cadena y la otra enlazada a una referencia de la variable de cadena calculada mediante una llamada a ref
. Cuando el valor de la variable cambia, la primera función continúa usando el valor antiguo y la segunda función usa el nuevo 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
Intercambia dos objetos function
.
template <class FT>
void swap(function<FT>& f1, function<FT>& f2);
Parámetros
FT
Tipo controlado por los objetos de función.
f1
El primer objeto de función.
f2
El segundo objeto de función.
Comentarios
La función devuelve f1.swap(f2)
.
Ejemplo
// 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