Denn das Ergebnis hängt von den Parametern der Vorlage ab, typedef typename
notwendig ist.
decltype
ist eine Standardfunktion von C++11. Es ist ein "Operator", der einen Ausdruck annimmt und einen Typ zurückgibt.
typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic
Si T()
nicht gültig ist ( T
nicht standardmäßig konstruierbar) werden Sie wollen declval
die eine Funktion ist, die einen Typ annimmt und einen bedeutungslosen, ungültigen Wert dieses Typs zurückgibt. declval
kann nur in unbewerteten Kontexten verwendet werden, wie z.B. decltype
.
typedef typename decltype( std::declval<T>().toCPD() ) D;
Vor C++11, decltype
war eine Nicht-Standard-Erweiterung von Microsofts MSVC-Compiler. Ihr Verhalten könnte durch die Standardisierung leicht verändert worden sein.
typeof
ist GCCs äquivalente Vor-C++11-Erweiterung wie decltype
, die auch in anderen Compilern geklont wurde. Hier ist die Dokumentation des GCC. Diese Seite bietet keinen Vergleich zwischen den Funktionen, aber sie stellt fest, dass typeof
muss aufgerufen werden __typeof__
bei Verwendung eines Standardmodus ( -std=c++YY
was Sie tun sollten immer do), und es ist sowohl in C als auch in C++ verfügbar.
Aus Gründen der C-Kompatibilität, __typeof__
löst einen Referenztyp nicht aus einem glvalue-Ausdruck auf. Das erklärt wahrscheinlich, warum die C++-Funktion nicht den selbsterklärenden Namen übernommen hat: GNU war nicht bereit, die Abwärtskompatibilität zu opfern, während Microsoft sich weniger um C kümmert und vielleicht weniger Änderungen benötigte.
result_of
ist eine C++11-Metafunktion (die zuvor in der ISO TR1-Bibliothek von 2006 standardisiert war). Sie ist eine Schablone, die einen aufrufbaren Typ (z. B. eine Funktion int(void)
, Funktionszeiger int(*)(void)
, Funktorklasse zur Implementierung operator()
oder Zeiger-auf-Member-Funktion &T::toCPD
) und eine Liste der Argumenttypen für diesen Typ und gibt den Rückgabetyp an, wenn der Aufruf funktionieren würde.
Zu verwenden result_of
mit einem Zeiger auf eine Mitgliedsfunktion zu verwenden, müssen Sie den Typ des übergeordneten Objekts in die Argumentliste als Surrogat für this
.
typedef typename std::result_of< decltype( & T::toCPD ) ( T * ) >::type D;
Dies ist jedoch sehr brüchig, denn &T::toCPD
kann nicht aufgelöst werden, wenn es eine Überladung gibt, z. B. eine Nicht-Konst-Version. Dies gilt trotz der Tatsache, dass T *
o T const *
müssen explizit ausgeschrieben werden! In den meisten Fällen ist es besser, wenn Sie decltype
y declval
.