Decltype Deklaration
-
Kurze Frage:
Kann mir jemand sagen, was folgende Deklaration zu bedeuten hat?
template<class T, class U> decltype((*(T*)0)+(*(U*)0)) add(T t, U u)Es handelt sich um einen duch VS2010 unterstützten C++0x Code. Was decltype macht ist mir im allgemeinen klar, aber was hat ((T)0) zu bedeuteten?
Danke im voraus.
-
Pointer to T-Pointer.
-
(T*)0 ist ein Zeiger auf T mit dem wert NULL.
(T)0 ist das Objekt vom Typ T, was dort liegt (wobei auf Adresse 0 kein Objekt liegen darf).cout<<((T)0) oder sowas führt natürlich sofort zu einer Schutzverletzung. Aber im decltype wird ja nur der Typ gebastelt, da geht das mal.
Der Code macht also nur
template<class T, class U> decltype(T()+U()) add(T t, U u), nur ein wenig besser, weil mein Code verlangt, daß T und U einen Standardkonstruktor haben.
-
Das soll das gleiche bewirken wie
template <class T, class U> auto add(T t, U u) -> decltype(t + u);Aus irgendeinem Grund benutzt der Schreiber aber nicht t und u, sondern macht sich Variablen aus Nullzeigern.
-
Was macht "->" Operator da?
-
Dass ist nicht der Pfeil-Operator, sondern eine neue Form der Funktionsdeklaration in C++0x. Er wird benötigt, da der Compiler hiermit nicht klarkommt:
template <class T, class U> decltype(t + u) add(T t, U u); ^ +------------------------------------ Was sind "t" und "u"?Deshalb nun diese neue Syntax.
-
Alternativ wird es ein Template
declvalgeben, mit dem man sich Werte/Objekte aus dem Nichts zaubern kann, zwecks Bauen eines Ausdrucks für decltype.#include <utility> ... using std::declval; ... decltype( declval<int>() + declval<double>() ) blah;@FrEEzE2046: Mit der auto...-> Syntax kann man Funktionen deklarieren/definieren. Nach -> kommt der Rückgabetyp, welcher sich so verzögern lässt. So ist dem Compiler auch bekannt, was t und u ist.
-
Danke für eure Antworten. Ich hatte leider noch keine Zeit mich intensiver einzulesen.
Noch schnell die Frage:
Wofür wird das std::forward im Body benötigt? Reicht nicht return t + u;?
-
FrEEzE2046 schrieb:
Wofür wird das std::forward im Body benötigt? Reicht nicht return t + u;?
Ich sehe in diesem Thread kein Beispiel mit std::forward. (!)
std::forward ist eigentlich dazu da, die "ürsprüngliche value-ness" wieder herzustellen. Es gibt Lvalue- und Rvalue-Ausdrücke. Zusammen mit Rvalue-Referenzen und einer speziellen Typ-Deduktionsregel erlaubt C++0x sogenanntes "perfect forwarding". std::forward ist eine Hilfsfunktion dafür.
void foo(int const&); // frisst lvalue-ausdrücke void foo(int &&); // frisst non-const rvalue ausdrücke template <typename T> void forwardor(T && x) { foo( std::forward<T>(x) ); } int main() { int i = 23; forwardor(i); // ruft foo(int const&) auf, da T=int& forwardor(i+1); // ruft foo(int &&) auf, da T=int }Die "value-ness" (L oder R) des Arguments bleibt in Form des Typ-Parameters T erhalten.
kk