Namespaces
Variants

std::declval

Von de.cppreference.net
 
 
Hilfsbibliothek
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programmhilfsmittel
Variadische Funktionen
Koroutinen-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationsoperatoren (veraltet in C++20)
Ganzzahlvergleichsfunktionen
(C++20)(C++20)(C++20)    
(C++20)
Swap und Typoperationen
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Allgemeine Vokabular-Typen
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
Definiert in Header <utility>
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
(seit C++11)
(bis C++14)
(nur in unevaluierten Kontexten)
template< class T >
std::add_rvalue_reference_t<T> declval() noexcept;
(seit C++14)
(nur in unevaluierten Kontexten)

Hilfsvorlage zum Schreiben von Ausdrücken, die in unevaluierten Kontexten erscheinen, typischerweise der Operand von decltype. In unevaluierten Kontexten wandelt diese Hilfsvorlage jeden Typ T (der ein unvollständiger Typ sein kann) in einen Ausdruck dieses Typs um und ermöglicht so die Verwendung von Memberfunktionen von T, ohne dass Konstruktoren durchlaufen werden müssen.

std::declval kann nur in unevaluierten Kontexten verwendet werden und muss nicht definiert sein; es ist ein Fehler, einen Ausdruck zu evaluieren, der diese Funktion enthält. Formal ist das Programm fehlerhaft, wenn diese Funktion odr-verwendet wird.

Parameter

(keine)

Rückgabewert

Kann nicht ausgewertet werden und gibt daher niemals einen Wert zurück. Der Rückgabetyp ist T&& (Referenzkollapsregeln finden Anwendung), es sei denn T ist (möglicherweise cv-qualifiziert) void , in welchem Fall der Rückgabetyp T ist.

Hinweise

std::declval wird häufig in Templates verwendet, wenn akzeptable Template-Parameter keinen gemeinsamen Konstruktor haben können, aber dieselbe Member-Funktion besitzen, deren Rückgabetyp benötigt wird.

Mögliche Implementierung

template<typename T>
typename std::add_rvalue_reference<T>::type declval() noexcept
{
    static_assert(false, "declval nicht erlaubt in einem ausgewerteten Kontext");
}

Beispiel

#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;     // Typ von n1 ist int
    decltype(std::declval<Default>().foo()) n2 = 1;     // gleich
//  decltype(NonDefault().foo())               n3 = n1; // Fehler: kein Standardkonstruktor
    decltype(std::declval<NonDefault>().foo()) n3 = n1; // Typ von n3 ist int
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n';
}

Ausgabe:

n1 = 1
n2 = 1
n3 = 1

Siehe auch

decltype Spezifizierer (C++11) ermittelt den Typ eines Ausdrucks oder einer Entität
(C++11) (entfernt in C++20) (C++17)
leitet den Ergebnistyp des Aufrufs eines aufrufbaren Objekts mit einer Reihe von Argumenten ab
(Klassentemplate)