Namespaces
Variants

std:: declval

From cppreference.net
Utilities library
Défini dans l'en-tête <utility>
template < class T >
typename std:: add_rvalue_reference < T > :: type declval ( ) noexcept ;
(depuis C++11)
(jusqu'à C++14)
(non évalué uniquement)
template < class T >
std:: add_rvalue_reference_t < T > declval ( ) noexcept ;
(depuis C++14)
(non évalué uniquement)

Modèle d'assistance pour écrire des expressions qui apparaissent dans des contextes non évalués , typiquement l'opérande de decltype . Dans un contexte non évalué, ce modèle d'assistance convertit tout type T (qui peut être un type incomplet) en une expression de ce type, permettant d'utiliser les fonctions membres de T sans avoir besoin de passer par des constructeurs.

std::declval ne peut être utilisé que dans des contextes non évalués et n'a pas besoin d'être défini ; il est erroné d'évaluer une expression contenant cette fonction. Formellement, le programme est mal formé si cette fonction est odr-utilisée .

Table des matières

Paramètres

(aucun)

Valeur de retour

Ne peut pas être évalué et ne renvoie donc jamais de valeur. Le type de retour est T&& (les règles de référence collapsing s'appliquent) sauf si T est (éventuellement qualifié cv) void , auquel cas le type de retour est T .

Notes

std::declval est couramment utilisé dans les templates où les paramètres de template acceptables peuvent n'avoir aucun constructeur en commun, mais possèdent la même fonction membre dont le type de retour est nécessaire.

Implémentation possible

template<typename T>
typename std::add_rvalue_reference<T>::type declval() noexcept
{
    static_assert(false, "declval non autorisé dans un contexte évalué");
}

Exemple

#include <iostream>
#include <utility>
struct Default
{
    int foo() const { return 1; }
};
struct NonDefault
{
    NonDefault() = delete;
    int foo() const { return 1; }
};
int main()
{
    decltype(Default().foo())               n1 = 1;     // type of n1 is int
    decltype(std::declval<Default>().foo()) n2 = 1;     // same
//  decltype(NonDefault().foo())               n3 = n1; // error: no default constructor
    decltype(std::declval<NonDefault>().foo()) n3 = n1; // type of n3 is int
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n';
}

Sortie :

n1 = 1
n2 = 1
n3 = 1

Voir aussi

decltype spécificateur (C++11) obtient le type d'une expression ou d'une entité
(C++11) (supprimé en C++20) (C++17)
déduit le type de résultat de l'invocation d'un objet appelable avec un ensemble d'arguments
(modèle de classe)