Visual C++ (2010) Bug



  • Hallihallo!

    Ich bin gerade über einen Compiler-Bug bei folgendem Code gestolpert:

    #include <type_traits>
    
    template<class T>
    void foo(T&& t)
    {
       typedef typename std::remove_reference<T>::type some_type;
    }
    
    void bar()
    {}
    
    int main()
    {
       foo(bar);
       return 0;
    }
    
    c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(197): error C2752: 'std::tr1::_Remove_reference<_Ty>':
    Mindestens eine teilweise Spezialisierung stimmt mit der Vorlagenargumentliste überein
    1>          with
    1>          [
    1>              _Ty=void (__cdecl &)(void)
    1>          ]
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(356): kann 'std::tr1::_Remove_reference<_Ty&&>' sein
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(350): oder "std::tr1::_Remove_reference<_Ty&>"
    1>          xxx\bug4263.cpp(6): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::tr1::remove_reference<_Ty>".
    1>          with
    1>          [
    1>              _Ty=void (__cdecl &)(void)
    1>          ]
    1>          xxx\bug4263.cpp(14): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void foo<void(__cdecl &)(void)>(T)".
    1>          with
    1>          [
    1>              T=void (__cdecl &)(void)
    1>          ]
    

    Leider gelingt es mir nicht, diesen Bug zu melden, da Microsoft scheinbar lieber Bug-Reports für VS2012 RC haben will. Wer von Euch VS 2012 RC hat, kann das ja mal testen und falls es immer noch nicht klappt, den Fehler melden ...

    - kk



  • VS2012 RC ist bugfrei 🤡



  • #include <type_traits> 
    
    template<class T> 
    void foo(T&& t) 
    { 
       typedef typename std::remove_reference<T>::type some_type; 
    } 
    
    void bar() 
    {} 
    
    int main() 
    { 
       foo(bar); 
       return 0; 
    }
    

    Wahnsinn. Schon wieder: Ein so einfacher Code, und so ein schwerer Bug.

    Mein Gott, ich werde niemals VC++ benutzen! Jetzt weiß ich erst was PI meinte, als er sagte, VC++ ist bei Templates zum kotzen.



  • Also nimmt mat ein & von T&& weg, so funktioniert es. VS 2010 unterstuetzt eben nicht wirklich C++11.



  • Der Haken ist glaub ich, dass der Compiler einfach intern && zu & bei Funktionsreferenzen ersetzt und dann auf einmal zwei gleich gut aussehende Spezialisierungen von remove_reference trifft.

    Zeus schrieb:

    VS2012 RC ist bugfrei 🤡

    Naja, sagen wir mal: Er kompiliert diesen Code fehlerfrei. 😉
    Aber gut zu wissen! Danke!

    kk



  • Imo ist das kein Bug, sondern exakt das vom Standard vorgesehene Verhalten. Du gehst da vermutlich einer afaik für Perfect Forwarding eingeführten Template Argument Deduction Rule auf den Leim: Wenn einem Function Template ein lvalue übergeben wird, wo eine rvalue Reference erwartet wird, dann ist der deduzierte Typ eine lvalue Reference (§ 14.8.2.1-3).

    Edit: Allerdings sollte std::remove_reference trotzdem funktionieren. Möglicherweise hat es allerdings was damit zu tun, dass sich an rvalue References nach dem Release von VC10 noch was geändert hat...



  • dot schrieb:

    Du gehst da vermutlich einer afaik für Perfect Forwarding eingeführten Template Argument Deduction Rule auf den Leim:

    Nein. Die Regel ist mir bewusst. Man kann das Problem weiter auf

    #include <type_traits>
    
    int main()
    {
    	typedef std::remove_reference<int(&)()>::type foo;
    }
    

    reduzieren, wobei eigentlich der Funktionstyp int() rauskommen sollte.

    Edit: Allerdings sollte std::remove_reference trotzdem funktionieren.

    So sehe ich das auch.


Anmelden zum Antworten