Namespaces
Variants

std:: apply

From cppreference.net
Utilities library
Definido en el encabezado <tuple>
template < class F, class Tuple >
constexpr decltype ( auto ) apply ( F && f, Tuple && t ) ;
(desde C++17)
(hasta C++23)
template < class F, tuple - like Tuple >
constexpr decltype ( auto ) apply ( F && f, Tuple && t ) noexcept ( /* ver más abajo */ ) ;
(desde C++23)

Invocar el objeto Callable f con los elementos de t como argumentos.

Dada la función de solo exposición apply-impl definida de la siguiente manera:

template < class F, class Tuple, std:: size_t ... I >
constexpr decltype ( auto )
apply-impl ( F && f, Tuple && t, std:: index_sequence < I... > ) // solo para exposición
{
return INVOKE ( std:: forward < F > ( f ) , std :: get < I > ( std:: forward < Tuple > ( t ) ) ... ) ;
}

El efecto es equivalente a:

return apply-impl ( std:: forward < F > ( f ) , std:: forward < Tuple > ( t ) ,
std:: make_index_sequence <
std:: tuple_size_v < std:: decay_t < Tuple >>> { } ) ;
.

Contenidos

Parámetros

f - Callable objeto invocable
t - tupla cuyos elementos se usarán como argumentos para f

Valor de retorno

El valor devuelto por f .

Excepciones

(ninguno)

(hasta C++23)
noexcept especificación:
noexcept (

noexcept ( std:: invoke ( std:: forward < F > ( f ) ,
std :: get < Is > ( std:: forward < Tuple > ( t ) ) ... ) )

)

donde Is... denota el pack :

(desde C++23)

Notas

Tuple no necesita ser std::tuple , y en su lugar puede ser cualquier cosa que admita std::get y std::tuple_size ; en particular, std::array y std::pair pueden ser utilizados.

(hasta C++23)

Tuple está restringido a ser tuple-like, es decir, cada tipo en él debe ser una especialización de std::tuple u otro tipo (como std::array y std::pair ) que modele tuple-like .

(desde C++23)
Macro de prueba de características Valor Std Característica
__cpp_lib_apply 201603L (C++17) std::apply

Ejemplo

#include <iostream>
#include <tuple>
#include <utility>
int add(int first, int second) { return first + second; }
template<typename T>
T add_generic(T first, T second) { return first + second; }
auto add_lambda = [](auto first, auto second) { return first + second; };
template<typename... Ts>
std::ostream& operator<<(std::ostream& os, std::tuple<Ts...> const& theTuple)
{
    std::apply
    (
        [&os](Ts const&... tupleArgs)
        {
            os << '[';
            std::size_t n{0};
            ((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);
            os << ']';
        }, theTuple
    );
    return os;
}
int main()
{
    // Correcto
    std::cout << std::apply(add, std::pair(1, 2)) << '\n';
    // Error: no se puede deducir el tipo de función
    // std::cout << std::apply(add_generic, std::make_pair(2.0f, 3.0f)) << '\n'; 
    // Correcto
    std::cout << std::apply(add_lambda, std::pair(2.0f, 3.0f)) << '\n'; 
    // ejemplo avanzado
    std::tuple myTuple{25, "Hello", 9.31f, 'c'};
    std::cout << myTuple << '\n';
}

Salida:

3
5
[25, Hello, 9.31, c]

Véase también

(C++11)
crea un objeto tuple del tipo definido por los tipos de argumento
(plantilla de función)
crea un tuple de referencias de reenvío
(plantilla de función)
construye un objeto con una tupla de argumentos
(plantilla de función)
(C++17) (C++23)
invoca cualquier objeto Callable con los argumentos dados y posibilidad de especificar el tipo de retorno (desde C++23)
(plantilla de función)