2013-02-28 8 views
8

Der folgende Code wurde mit VC++ Nov 2012 CTP kompiliert. Aber der Compiler gab eine Warnung ab.Warum gibt decltype (* this) nicht den richtigen Typ zurück?

Ich frage mich nur, ob dies ein Fehler von VC++ November 2012 CTP ist.

struct A 
{ 
    int n; 

    A(int n) 
     : n(n) 
    {} 

    int Get() const 
    { 
     return n; 
    } 

    int Get() 
    { 
     // 
     // If using "static_cast<const A&>(*this).Get();" instead, then OK. 
     // 
     return static_cast<const decltype(*this)&>(*this).Get(); // Warning! 
    } 
}; 

int main() 
{ 
    A a(8); 

    // 
    // warning C4717: 'A::Get' : recursive on all control paths, 
    // function will cause runtime stack overflow 
    // 
    a.Get(); 
} 
+0

Wenn Sie nicht wirklich mehr als nur einen Wert in der Konstanten 'Get' zurückgeben, können Sie das Gleiche auch in der nicht-konstanten 'Get'-Funktion tun. Ich sehe eigentlich keinen Grund für das nicht-konstante "Get". –

+5

Der Beispielcode dient nur zum Nachweis des Konzepts. Die wirkliche Funktion von Get() ist hier sinnlos. – xmllmx

+0

Ist 'a' nicht schon const? Warum sollte es überhaupt vor der nicht-konstanten "Get" -Funktion warnen? – Shahbaz

Antwort

17

decltype auf einen Ausdruck angewendet, die Sie eine Referenz nicht ein id-Ausdruck ist gibt, so decltype(*this) bereits A&, und Sie können nicht, dass const wieder machen. Wenn Sie wirklich verwenden decltype wollten, könnten Sie so etwas tun:

static_cast<std::decay<decltype(*this)>::type const &>(*this) 

Oder auch dies:

static_cast<std::add_lvalue_reference< 
       std::add_const< 
         std::decay<decltype(*this)>::type 
       >::type 
      >::type 
>(*this) 

Natürlich ist es viel einfacher, nur static_cast<A const &>(*this) zu sagen.

+0

Abschließend ist die Warnung gültig. –

+0

@LightnessRacesinOrbit: Ich bin überrascht, dass es nicht wirklich ein * Fehler * ist. –

+0

@KerrekSB: GCC gibt Fehler, nicht nur Warnung! – Nawaz

Verwandte Themen