decltype-Spezifizierer (seit C++11)
Untersucht den deklarierten Typ einer Entität oder den Typ und die Wertkategorie eines Ausdrucks.
Inhalt |
[bearbeiten] Syntax
decltype ( entity ) |
(1) | ||||||||
decltype ( expression ) |
(2) | ||||||||
[bearbeiten] Erklärung
|
Wenn das Argument ein nicht in Klammern gesetzter id-Ausdruck ist, der eine strukturierte Bindung benennt, liefert decltype den *Referenztyp* (beschrieben in der Spezifikation der strukturierten Bindungsdeklaration). |
(seit C++17) |
|
Wenn das Argument ein nicht in Klammern gesetzter id-Ausdruck ist, der einen Nicht-Typ-Vorlagenparameter benennt, liefert decltype den Typ des Vorlagenparameters (nach Durchführung einer notwendigen Typableitung, falls der Vorlagenparameter mit einem Platzhaltertyp deklariert wurde). Der Typ ist nicht const, auch wenn die Entität ein Vorlagenparameterobjekt ist (was ein const-Objekt ist). |
(seit C++20) |
T ist, und|
Wenn expression ein Funktionsaufruf ist, der einen prvalue vom Klassentyp zurückgibt, oder ein Komma-Ausdruck, dessen rechtes Operand ein solcher Funktionsaufruf ist, wird für diesen prvalue kein temporäres Objekt eingeführt. |
(bis C++17) |
|
Wenn expression ein prvalue ist außer einem (möglicherweise in Klammern gesetzten) sofortigen Aufruf(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 ist, er als gewöhnlicher lvalue-Ausdruck behandelt wird, sodass decltype(x) und decltype((x)) oft unterschiedliche Typen sind.
decltype ist nützlich, wenn Typen deklariert werden, die mit Standardnotationen schwierig oder unmöglich zu deklarieren sind, wie z. B. Lambda-bezogene Typen oder Typen, die von Vorlagenparametern abhängen.
[bearbeiten] Hinweise
| Feature-Testmakro | Wert | Std | Feature |
|---|---|---|---|
__cpp_decltype |
200707L |
(C++11) | decltype |
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
#include <cassert> #include <iostream> #include <type_traits> struct A { double x; }; const A* a; decltype(a->x) y; // type of y is double (declared type) decltype((a->x)) z = y; // type of z is const double& (lvalue expression) template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // return type depends on template parameters // return type can be deduced since C++14 { 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*)>, "Just returning auto isn't perfect forwarding."); decltype(auto) getRefFwdGood(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>, "Returning decltype(auto) perfectly forwards the return type."); // Alternatively: auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>, "Returning decltype(return expression) also perfectly forwards the return type."); 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)>, "The type of a lambda function is unique and unnamed"); decltype(f) g = f; std::cout << f(3, 3) << ' ' << g(3, 3) << '\n'; }
Ausgabe
42 42
[bearbeiten] Referenzen
| Erweiterter Inhalt |
|---|
|
| Dieser Abschnitt ist unvollständig Grund: Korrektur erforderlich. Siehe: Talk: Falsche Referenzen. |
[bearbeiten] Siehe auch
auto-Spezifizierer (C++11) |
spezifiziert einen Typ, der aus einem Ausdruck abgeleitet wird |
| (C++11) |
erhält eine Referenz auf ein Objekt des Typ-Template-Arguments zur Verwendung in einem nicht-ausgewerteten Kontext (Funktionsvorlage) |
| (C++11) |
prüft, ob zwei Typen gleich sind (Klassenvorlage) |
| C-Dokumentation für typeof
| |