13 Stimmen

decltype, result_of, oder typeof?

Ich habe:

class A {
public:
    B           toCPD() const;

Und:

template<typename T>
class Ev {
public:
    typedef result_of(T::toCPD()) D;

Nach der Instanziierung Ev<A> sagt der Compiler:

meta.h:12: Fehler: 'T::toCPD' ist kein Typ

weder decltype noch typeof funktionieren.

34voto

Potatoswatter Punkte 130562

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 .

3voto

Result_of ist weder eine Funktion noch ein Operator. result_of ist eine Metafunktion, die eine Funktion als Vorlage und die Einstellung des Ergebnistyps auf den Mitgliedstyp

typedef typename result_of<T::toCPD()>::type D;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X