decltype
specifier
(since C++11)
Untersucht den deklarierten Typ einer Entität oder den Typ und Wertkategorie eines Ausdrucks.
Inhaltsverzeichnis |
Syntax
decltype (
Entität
)
|
(1) | ||||||||
decltype (
Ausdruck
)
|
(2) | ||||||||
Erklärung
|
Wenn das Argument ein nicht in Klammern gesetzter id-expression ist, der eine structured binding benennt, dann liefert decltype den referenzierten Typ (beschrieben in der Spezifikation der structured binding Deklaration). |
(seit C++17) |
|
Wenn das Argument ein nicht in Klammern gesetzter id-expression ist, der einen constant template parameter benennt, dann liefert decltype den Typ des Template-Parameters (nach Durchführung etwaiger Typableitung falls der Template-Parameter mit einem Platzhaltertyp deklariert wurde). Der Typ ist non-const selbst wenn die Entität ein Template-Parameter-Objekt (welches ein const-Objekt ist) ist. |
(seit C++20) |
T
ist, und
|
Wenn expression ein Funktionsaufruf ist, der einen Prvalue vom Klassentyp zurückgibt, oder ein Komma-Ausdruck ist, dessen rechter Operand ein solcher Funktionsaufruf ist, wird kein temporäres Objekt für diesen Prvalue eingeführt. |
(bis C++17) |
|
Wenn expression ein Prvalue ist (außer einem (möglicherweise in Klammern gesetzten) Immediate Invocation (seit C++20) , wird kein temporäres Objekt aus diesem Prvalue materialisiert : ein solcher Prvalue hat kein Ergebnisobjekt. |
(seit C++17) |
Beachten Sie, dass wenn der Name eines Objekts in Klammern gesetzt wird, er als gewöhnlicher Lvalue-Ausdruck behandelt wird, daher sind decltype ( x ) und decltype ( ( x ) ) oft unterschiedliche Typen.
decltype
ist nützlich, wenn Typen deklariert werden, die schwierig oder unmöglich mit Standardnotation zu deklarieren sind, wie lambda-bezogene Typen oder Typen, die von Template-Parametern abhängen.
Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_decltype
|
200707L
|
(C++11) | decltype |
Schlüsselwörter
Beispiel
#include <cassert> #include <iostream> #include <type_traits> struct A { double x; }; const A* a; decltype(a->x) y; // Typ von y ist double (deklarierter Typ) decltype((a->x)) z = y; // Typ von z ist const double& (Lvalue-Ausdruck) template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // Rückgabetyp hängt von Template-Parametern ab // Rückgabetyp kann seit C++14 abgeleitet werden { return t + u; } const int& getRef(const int* p) { return *p; } static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>); auto getRefFwdBad(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>, "Nur auto zurückzugeben ist kein perfektes Forwarding."); decltype(auto) getRefFwdGood(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>, "Rückgabe von decltype(auto) forwarded den Rückgabetyp perfekt."); // Alternativ: auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>, "Rückgabe von decltype(Rückgabeausdruck) forwarded den Rückgabetyp ebenfalls perfekt."); int main() { int i = 33; decltype(i) j = i * 2; static_assert(std::is_same_v<decltype(i), decltype(j)>); assert(i == 33 && 66 == j); auto f = [i](int av, int bv) -> int { return av * bv + i; }; auto h = [i](int av, int bv) -> int { return av * bv + i; }; static_assert(!std::is_same_v<decltype(f), decltype(h)>, "Der Typ einer Lambda-Funktion ist eindeutig und unbenannt"); decltype(f) g = f; std::cout << f(3, 3) << ' ' << g(3, 3) << '\n'; }
Ausgabe:
42 42
Referenzen
| Erweiterter Inhalt |
|---|
|
|
Dieser Abschnitt ist unvollständig
Grund: Erfordert Korrektur. Siehe: Talk: Wrong References . |
Siehe auch
auto
Spezifizierer
(C++11)
|
gibt einen aus einem Ausdruck abgeleiteten Typ an |
|
(C++11)
|
erhält eine Referenz auf ein Objekt des Template-Typarguments zur Verwendung in einem nicht ausgewerteten Kontext
(Funktionstemplate) |
|
(C++11)
|
prüft, ob zwei Typen identisch sind
(Klassentemplate) |
|
C-Dokumentation
für
typeof
|
|