Namespaces
Variants

std:: apply

From cppreference.net
Utilities library
Défini dans l'en-tête <tuple>
template < class F, class Tuple >
constexpr decltype ( auto ) apply ( F && f, Tuple && t ) ;
(depuis C++17)
(jusqu'à C++23)
template < class F, tuple - like Tuple >
constexpr decltype ( auto ) apply ( F && f, Tuple && t ) noexcept ( /* voir ci-dessous */ ) ;
(depuis C++23)

Invoquez l'objet Callable f avec les éléments de t comme arguments.

Étant donné la fonction d'exposition uniquement apply-impl définie comme suit :

template < class F, class Tuple, std:: size_t ... I >
constexpr decltype ( auto )
apply-impl ( F && f, Tuple && t, std:: index_sequence < I... > ) // à titre d'illustration uniquement
{
return INVOKE ( std:: forward < F > ( f ) , std :: get < I > ( std:: forward < Tuple > ( t ) ) ... ) ;
}

L'effet est équivalent à :

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

Table des matières

Paramètres

f - Callable objet à invoquer
t - tuple dont les éléments doivent être utilisés comme arguments pour f

Valeur de retour

La valeur retournée par f .

Exceptions

(aucun)

(jusqu'à C++23)
noexcept spécification :
noexcept (

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

)

Is... désigne le pack :

(depuis C++23)

Notes

Tuple n'a pas besoin d'être std::tuple , et peut être n'importe quel type qui supporte std::get et std::tuple_size ; en particulier, std::array et std::pair peuvent être utilisés.

(jusqu'à C++23)

Tuple est contraint à être tuple-like, c'est-à-dire que chaque type doit être une spécialisation de std::tuple ou un autre type (tel que std::array et std::pair ) qui modélise tuple-like .

(depuis C++23)
Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_apply 201603L (C++17) std::apply

Exemple

#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()
{
    // OK
    std::cout << std::apply(add, std::pair(1, 2)) << '\n';
    // Erreur : impossible de déduire le type de fonction
    // std::cout << std::apply(add_generic, std::make_pair(2.0f, 3.0f)) << '\n'; 
    // OK
    std::cout << std::apply(add_lambda, std::pair(2.0f, 3.0f)) << '\n'; 
    // exemple avancé
    std::tuple myTuple{25, "Hello", 9.31f, 'c'};
    std::cout << myTuple << '\n';
}

Sortie :

3
5
[25, Hello, 9.31, c]

Voir aussi

(C++11)
crée un objet tuple du type défini par les types d'arguments
(modèle de fonction)
crée un tuple de références de transfert
(modèle de fonction)
construit un objet avec un tuple d'arguments
(modèle de fonction)
(C++17) (C++23)
invoque tout objet Callable avec les arguments donnés et possibilité de spécifier le type de retour (depuis C++23)
(modèle de fonction)