<functional>
funzioni
Queste funzioni sono deprecate in C++11 e rimosse in C++17:
bind1st
bind2nd
mem_fun
mem_fun_ref
ptr_fun
Queste funzioni sono deprecate in C++17:
bind
Associa gli argomenti a un oggetto richiamabile.
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);
Parametri
FT
Tipo di oggetto da chiamare. Ad esempio, il tipo di funzione, oggetto funzione, puntatore/riferimento di funzione o puntatore a funzione membro.
RTy
Tipo restituito. Se specificato, sarà il tipo restituito della chiamata associata. In caso contrario, il tipo restituito è il tipo restituito di FT
.
TN
Tipo dell'ennesimo argomento di chiamata.
fn
Oggetto da chiamare.
tN
Ennesimo argomento di chiamata.
Osservazioni:
I tipi FT, T1, T2, ..., TN
devono essere copiabili e INVOKE(fn, t1, ..., tN)
devono essere un'espressione valida per alcuni valori w1, w2, ..., wN
.
La prima funzione modello restituisce un wrapper di chiamata di inoltro g
con un tipo di risultato debole. L'effetto di g(u1, u2, ..., uM)
è INVOKE(f, v1, v2, ..., vN,
invoke_result<FT cv (V1, V2, ..., VN)>::type)
, dove cv
è il qualificatore cv di g
e i valori e i v1, v2, ..., vN
tipi degli argomenti associati vengono determinati come specificato di seguito. È possibile usarla per associare argomenti a un oggetto chiamabile in modo da avere un oggetto chiamabile con un elenco di argomenti personalizzato.
La seconda funzione modello restituisce un wrapper di chiamata di inoltro g
con un tipo nidificato result_type
sinonimo di RTy
. L'effetto di g(u1, u2, ..., uM)
è INVOKE(f, v1, v2, ..., vN, RTy)
, dove cv
corrisponde ai qualificatori CV di g
e i valori e i tipi degli argomenti associati v1, v2, ..., vN
vengono determinati come specificato di seguito. È possibile usarla per associare argomenti a un oggetto chiamabile in modo da avere un oggetto chiamabile con un elenco di argomenti personalizzato e con un tipo restituito specificato.
I valori degli argomenti associati v1, v2, ..., vN
e i rispettivi tipi corrispondenti V1, V2, ..., VN
dipendono dal tipo dell'argomento corrispondente ti
di tipo Ti
nella chiamata a bind
e dai qualificatori CV cv
del wrapper di chiamata g
come segue:
Se ti
è di tipo reference_wrapper<T>
l'argomento vi
è ti.get()
e il relativo tipo Vi
è T&
;
Se il valore di std::is_bind_expression<Ti>::value
è true
l'argomento vi
e ti(u1, u2, ..., uM)
il relativo tipo Vi
è result_of<Ti
cv
(U1&, U2&, ..., UN&>::type
;
Se il valore j
di std::is_placeholder<Ti>::value
non è zero, l'argomento vi
è uj
e il relativo tipo Vi
è Uj&
;
In caso contrario, l'argomento vi
è ti
e il relativo tipo Vi
è Ti
cv
&
.
Ad esempio, data una funzione f(int, int)
, l'espressione bind(f, _1, 0)
restituisce un wrapper di chiamata di inoltro cw
in modo che cw(x)
chiami f(x, 0)
. L'espressione bind(f, 0, _1)
restituisce un wrapper di chiamata di inoltro cw
in modo che cw(x)
chiami f(0, x)
.
Il numero di argomenti in una chiamata a bind
e l'argomento fn
deve essere uguale al numero di argomenti che possono essere passati all'oggetto fn
chiamabile . Ad esempio, bind(cos, 1.0)
è corretto ed entrambi e bind(cos)
bind(cos, _1, 0.0)
non sono corretti.
Il numero degli argomenti presenti nella chiamata di funzione al wrapper di chiamata restituito da bind
deve essere almeno uguale al valore con numero più alto di is_placeholder<PH>::value
per tutti gli argomenti segnaposto nella chiamata a bind
. Ad esempio, bind(cos, _2)(0.0, 1.0)
è corretto (e restituisce cos(1.0)
) e bind(cos, _2)(0.0)
non è corretto.
Esempio
// 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
Funzione modello helper che crea un adattatore per convertire un oggetto funzione binaria in un oggetto funzione unario. Associa il primo argomento della funzione binaria a un valore specificato. Deprecato in C++11, rimosso in C++17.
template <class Operation, class Type>
binder1st <Operation> bind1st (const Operation& func, const Type& left);
Parametri
func
Oggetto funzione binaria da convertire in un oggetto funzione unaria.
left
Valore a cui deve essere associato il primo argomento dell'oggetto funzione binaria.
Valore restituito
Oggetto funzione unario risultante dall'associazione del primo argomento dell'oggetto funzione binaria al valore left
.
Osservazioni:
I binder di funzione sono un tipo di adattatore di funzione. Poiché restituiscono oggetti funzione, possono essere usati in determinati tipi di composizione di funzioni per costruire espressioni più complesse e potenti.
Se func
è un oggetto di tipo Operation
ed c
è una costante, bind1st( func, c )
è uguale al costruttore binder1st<Operation>(func, c)
della binder1st
classe ed è più pratico da usare.
Esempio
// 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
Funzione modello helper che crea un adattatore per convertire un oggetto funzione binaria in un oggetto funzione unario. Associa il secondo argomento della funzione binaria a un valore specificato. Deprecato in C++11, rimosso in C++17.
template <class Operation, class Type>
binder2nd <Operation> bind2nd(const Operation& func, const Type& right);
Parametri
func
Oggetto funzione binaria da convertire in un oggetto funzione unaria.
right
Valore a cui deve essere associato il secondo argomento dell'oggetto funzione binaria.
Valore restituito
Risultato dell'oggetto funzione unario dell'associazione del secondo argomento dell'oggetto funzione binaria a right
.
Osservazioni:
I binder di funzione sono un tipo di adattatore di funzione. Poiché restituiscono oggetti funzione, possono essere usati in determinati tipi di composizione di funzioni per costruire espressioni più complesse e potenti.
Se func
è un oggetto di tipo Operation
ed c
è una costante, bind2nd(func, c)
è uguale al costruttore binder2nd<Operation>(func, c)
della binder2nd
classe e più pratico da usare.
Esempio
// 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
Oggetto funzione predefinito che esegue un'operazione AND bit per bit (binario operator&
) sui relativi argomenti.
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));
};
Parametri
Type
, T
, U
Qualsiasi tipo che supporta un operator&
che accetta gli operandi dei tipi specificati o dedotti.
Left
Operando sinistro dell'operazione AND bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto T
.
Right
Operando destro dell'operazione AND bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto U
.
Valore restituito
Risultato di Left & Right
. Il modello specializzato esegue un inoltro perfetto del risultato, con il tipo restituito da operator&
.
Osservazioni:
Il funtore bit_and
è limitato ai tipi integrali per i tipi di dati di base o ai tipi definiti dall'utente che implementano un oggetto operator&
binario.
bit_not
Oggetto funzione predefinito che esegue un'operazione di complemento bit per bit (NOT) (unaria operator~
) sul relativo argomento. Aggiunta in 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));
};
Parametri
Type
Tipo che supporta un oggetto operator~
unario.
Right
Operando dell'operazione di complemento bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue l'inoltro perfetto di un argomento di riferimento lvalue o rvalue del tipo dedotto Type
.
Valore restituito
Risultato di ~ Right
. Il modello specializzato esegue un inoltro perfetto del risultato, con il tipo restituito da operator~
.
Osservazioni:
Il funtore bit_not
è limitato ai tipi integrali per i tipi di dati di base o ai tipi definiti dall'utente che implementano un oggetto operator~
binario.
bit_or
Oggetto funzione predefinito che esegue un'operazione OR bit per bit (operator|
) sui relativi argomenti.
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));
};
Parametri
Type
, T
, U
Qualsiasi tipo che supporta un operator|
che accetta gli operandi dei tipi specificati o dedotti.
Left
Operando sinistro dell'operazione OR bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto T
.
Right
Operando destro dell'operazione OR bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto U
.
Valore restituito
Risultato di Left | Right
. Il modello specializzato esegue un inoltro perfetto del risultato, con il tipo restituito da operator|
.
Osservazioni:
Il funtore bit_or
è limitato ai tipi integrali per i tipi di dati di base o ai tipi definiti dall'utente che implementano operator|
.
bit_xor
Oggetto funzione predefinito che esegue un'operazione XOR bit per bit (binario operator^
) sui relativi argomenti.
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));
};
Parametri
Type
, T
, U
Qualsiasi tipo che supporta un operator^
che accetta gli operandi dei tipi specificati o dedotti.
Left
Operando sinistro dell'operazione XOR bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto T
.
Right
Operando destro dell'operazione XOR bit per bit. Il modello non specializzato accetta un argomento di riferimento lvalue di tipo Type
. Il modello specializzato esegue un inoltro perfetto degli argomenti di riferimento lvalue e rvalue del tipo dedotto U
.
Valore restituito
Risultato di Left ^ Right
. Il modello specializzato esegue un inoltro perfetto del risultato, con il tipo restituito da operator^
.
Osservazioni:
Il funtore bit_xor
è limitato ai tipi integrali per i tipi di dati di base o ai tipi definiti dall'utente che implementano un oggetto operator^
binario.
cref
Costruisce un oggetto reference_wrapper
di tipo const da un argomento.
template <class Ty>
reference_wrapper<const Ty> cref(const Ty& arg);
template <class Ty>
reference_wrapper<const Ty> cref(const reference_wrapper<Ty>& arg);
Parametri
Ty
Tipo di argomento di cui eseguire il wrapping.
arg
Argomento di cui eseguire il wrapping.
Osservazioni:
La prima funzione restituisce reference_wrapper<const Ty>(arg.get())
. Usarla per eseguire il wrapping di un riferimento const. La seconda funzione restituisce reference_wrapper<const Ty>(arg)
. Usarla per eseguire nuovamente il wrapping di un riferimento già sottoposto a wrapping come riferimento const.
Esempio
// 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
Richiama qualsiasi oggetto chiamabile con gli argomenti specificati. Aggiunta in C++17.
template <class Callable, class... Args>
invoke_result_t<Callable, Args...>
invoke(Callable&& fn, Args&&... args) noexcept(/* specification */);
Parametri
Callable
Tipo di oggetto da chiamare.
Args
Tipi di argomenti di chiamata.
fn
Oggetto da chiamare.
args
Argomenti della chiamata.
specification
std::is_nothrow_invocable_v<Callable, Args>)
Specifica noexcept
.
Osservazioni:
Richiama l'oggetto fn
chiamabile usando i args
parametri . In effetti, INVOKE(std::forward<Callable>(fn), std::forward<Args>(args)...)
, dove la pseudo-funzione INVOKE(f, t1, t2, ..., tN)
indica una delle operazioni seguenti:
(t1.*f)(t2, ..., tN)
quandof
è un puntatore alla funzione membro di classeT
et1
è un oggetto di tipoT
, un riferimento a un oggetto di tipoT
o un riferimento a un oggetto di un tipo derivato daT
. Cioè, quandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
è vero.(t1.get().*f)(t2, ..., tN)
quandof
è un puntatore alla funzione membro della classeT
edstd::decay_t<decltype(t1)>
è una specializzazione distd::reference_wrapper
.((*t1).*f)(t2, ..., tN)
quandof
è un puntatore alla funzione membro della classeT
et1
non è uno dei tipi precedenti.t1.*f
quando N == 1 ef
è un puntatore ai dati dei membri di una classeT
et1
è un oggetto di tipoT
, un riferimento a un oggetto di tipoT
o un riferimento a un oggetto di un tipo derivato daT
. Cioè, quandostd::is_base_of<T, std::decay_t<decltype(t1)>>::value
è vero.t1.get().*f
quando N == 1 ef
è un puntatore ai dati dei membri di una classeT
edstd::decay_t<decltype(t1)>
è una specializzazione distd::reference_wrapper
.(*t1).*f
quando N == 1 ef
è un puntatore ai dati dei membri di una classeT
et1
non è uno dei tipi precedenti.f(t1, t2, ..., tN)
in tutti gli altri casi.
Per informazioni sul tipo di risultato di un oggetto chiamabile, vedere invoke_result. Per i predicati sui tipi chiamabili, vedere is_invocable, is_invocable_r, is_nothrow_invocable is_nothrow_invocable_r classi.
Esempio
// 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 wrapper di chiamata semplice.
template <class RTy, class Ty>
unspecified mem_fn(RTy Ty::*pm);
Parametri
RTy
Tipo restituito della funzione di cui è stato eseguito il wrapping.
Ty
Tipo di puntatore a funzione membro.
Osservazioni:
La funzione modello restituisce un wrapper cw
di chiamata semplice , con un tipo di risultato debole, in modo che l'espressione cw(t, a2, ..., aN)
sia uguale a INVOKE(pm, t, a2, ..., aN)
. Non genera eccezioni.
Il wrapper di chiamata restituito deriva da std::unary_function<cv Ty*, RTy>
(e definisce il tipo result_type
annidato come sinonimo di RTy
e il tipo annidato come sinonimo di cv Ty*
) solo se il tipo argument_type
Ty
è un puntatore alla funzione membro con qualificatore cv
cv che non accetta argomenti.
Il wrapper di chiamata restituito deriva da std::binary_function<cv Ty*, T2, RTy>
(e definisce il tipo result_type
annidato come sinonimo di RTy
, il tipo annidato come sinonimo di cv Ty*
e il tipo second argument_type
first argument_type
annidato come sinonimo di T2
) solo se il tipo Ty
è un puntatore alla funzione membro con cv-qualificatore cv
che accetta un argomento, di tipo T2
.
Esempio
// 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
Funzioni di modello helper utilizzate per costruire gli adattatori dell'oggetto funzione per funzioni membro una volta inizializzate con gli argomenti di puntatore. Deprecato in C++11 per mem_fn
e bind
e rimosso in 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);
Parametri
pMem
Puntatore alla funzione membro di classe Type
da convertire in un oggetto funzione.
Valore restituito
Oggetto const
funzione o non const di tipo mem_fun_t
o mem_fun1_t
.
Esempio
// 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
Funzioni modello helper usate per costruire gli adattatori dell'oggetto funzione per funzioni membro se inizializzate mediante argomenti di riferimento. Deprecato in C++11, rimosso in 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);
Parametri
pMem
Puntatore alla funzione membro di classe Type
da convertire in un oggetto funzione.
Valore restituito
Oggetto funzione const
o non_const
di tipo mem_fun_ref_t
o mem_fun1_ref_t
.
Esempio
// 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
Restituisce il complemento di un predicato unario. Deprecato per not_fn
in C++17.
template <class UnaryPredicate>
unary_negate<UnaryPredicate> not1(const UnaryPredicate& predicate);
Parametri
predicate
Predicato unario da negare.
Valore restituito
Predicato unario che è la negazione del predicato unario modificato.
Osservazioni:
Se un unary_negate
oggetto viene costruito da un predicato predicate(x)
unario , restituisce !predicate(x)
.
Esempio
// 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
Restituisce il complemento di un predicato binario. Deprecato per not_fn
in C++17.
template <class BinaryPredicate>
binary_negate<BinaryPredicate> not2(const BinaryPredicate& func);
Parametri
func
Predicato binario da negare.
Valore restituito
Predicato binario che è la negazione del predicato binario modificato.
Osservazioni:
Se un binary_negate
oggetto viene costruito da un predicato binary_predicate(x, y)
binario , restituisce !binary_predicate(x, y)
.
Esempio
// 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
Il not_fn
modello di funzione accetta un oggetto chiamabile e restituisce un oggetto chiamabile. Quando l'oggetto chiamabile restituito viene richiamato successivamente con alcuni argomenti, li passa all'oggetto chiamabile originale e nega logicamente il risultato. Mantiene il comportamento di qualificazione e categoria di valori const dell'oggetto chiamabile di cui è stato eseguito il wrapping. not_fn
è una novità di C++17 e sostituisce il deprecato std::not1
, std::not2
, std::unary_negate
e std::binary_negate
.
template <class Callable>
/* unspecified */ not_fn(Callable&& func);
Parametri
func
Oggetto chiamabile utilizzato per costruire il wrapper di chiamata di inoltro.
Osservazioni:
La funzione modello restituisce un wrapper di chiamata come return call_wrapper(std::forward<Callable>(func))
, in base a questa classe di sola esposizione:
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;
};
Il costruttore esplicito nell'oggetto func
chiamabile richiede il tipo std::decay_t<Callable>
per soddisfare i requisiti di MoveConstructible
e is_constructible_v<FD, Callable>
deve essere true. Inizializza l'oggetto fd
chiamabile di cui è stato eseguito il wrapping da std::forward<Callable>(func)
e genera qualsiasi eccezione generata dalla costruzione di fd
.
Il wrapper espone gli operatori di chiamata distinti per categoria di riferimento lvalue o rvalue e qualifica const, come illustrato di seguito:
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...)>>());
I primi due sono uguali a return !std::invoke(fd, std::forward<Args>(args)...)
. I secondi due sono uguali a return !std::invoke(std::move(fd), std::forward<Args>(args)...)
.
Esempio
// 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
Funzioni modello helper usate per convertire i puntatori a funzioni unarie e binarie rispettivamente in funzioni adattabili unarie e binarie. Deprecato in C++11, rimosso in 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));
Parametri
pfunc
Puntatore a funzione unaria o binaria da convertire in una funzione adattabile.
Valore restituito
La prima funzione modello restituisce la funzione unaria pointer_to_unary_function<Arg
, Result
>(* ). pfunc
La seconda funzione modello restituisce la funzione binaria pointer_to_binary_functionArg1
<, Arg2
, Result
>(* pfunc
).
Osservazioni:
Un puntatore a funzione è un oggetto funzione. Può essere passato a qualsiasi algoritmo che prevede una funzione come parametro, ma non è adattabile. Le informazioni sui tipi annidati sono necessarie per usarle con un adattatore, ad esempio per associare un valore a esso o per negarlo. La conversione dei puntatori a funzioni unarie e binarie mediante la funzione helper ptr_fun
consente agli adattatori di funzione di interagire con tali puntatori.
Esempio
// 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
Costruisce un oggetto reference_wrapper
da un argomento.
template <class Ty>
reference_wrapper<Ty> ref(Ty& arg);
template <class Ty>
reference_wrapper<Ty> ref(reference_wrapper<Ty>& arg);
Valore restituito
Riferimento a arg
, in particolare, reference_wrapper<Ty>(arg)
.
Esempio
L'esempio seguente definisce due funzioni: una associata a una variabile di tipo stringa, l'altra associata a un riferimento della variabile di tipo stringa calcolata in base a una chiamata a ref
. Quando cambia il valore della variabile, la prima funzione continua a usare il valore precedente, mentre la seconda usa il nuovo valore.
#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
Scambia due oggetti function
.
template <class FT>
void swap(function<FT>& f1, function<FT>& f2);
Parametri
FT
Tipo controllato dagli oggetti funzione.
f1
Primo oggetto funzione.
f2
Secondo oggetto funzione.
Osservazioni:
La funzione restituisce f1.swap(f2)
.
Esempio
// 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