Umgehung des const-Referenz-Status von Temporaries



  • Mr. N schrieb:

    Was hat das mit meinem Problem zu tun oder versteh ich den Thread nur nicht?

    Sry. Siehe mein Edit. Habe einfach blind draufgeschaut und dachte es geht nur um das binden von temporären Objekten an Referenzparametern ....



  • KasF schrieb:

    Mr. N schrieb:

    Was hat das mit meinem Problem zu tun oder versteh ich den Thread nur nicht?

    Sry. Siehe mein Edit. Habe einfach blind draufgeschaut und dachte es geht nur um das binden von temporären Objekten an Referenzparametern ....

    Was mich irritiert ist, dass gleich der erste Code in dem Thread nicht compiliert.

    <stdin>:9: error: invalid initialization of non-const reference of type 'X&' from a temporary of type 'X'
    

  • Mod

    Der Thread ist alt. Vermutlich war das noch mit vc6 gemacht. vc hat eine Erweiterung, die es erlaubt, rvalues auch an non-const Referenzen zu binden.



  • Muss ich wirklich über self() gehen? Gibt es nicht eine weniger aufdringliche Variante? Wie problematisch wäre es, einfach auf den verbreiteten Compiler-Bug zu vertrauen, dass mein Code geht? (GCC 4.3 hat keine Probleme mit ihm.)



  • Undefined Behaviour in Kauf nehmen!?
    Was kommt danach? Gutheißen von Angriffskriegen und Rechtsextremismus?



  • kenner der dummköpfe schrieb:

    Undefined Behaviour in Kauf nehmen!?
    Was kommt danach? Gutheißen von Angriffskriegen und Rechtsextremismus?

    😃 👍



  • Mr. N schrieb:

    Muss ich wirklich über self() gehen? Gibt es nicht eine weniger aufdringliche Variante? Wie problematisch wäre es, einfach auf den verbreiteten Compiler-Bug zu vertrauen, dass mein Code geht? (GCC 4.3 hat keine Probleme mit ihm.)

    Wenns portabel sein soll schon.
    Für MSVC alleine brauchst du IIRC nichtmal den "operator xyz&", das ist ne "non-std-extension" (MSVC verweigert es auch wenn man die "non-std-extension" ausschaltet).



  • reicht dir vielleicht sowas?

    template<class T> struct ConstHelper
    {
       typedef int type;
    };
    
    template<class T> struct ConstHelper<T const>
    {
       template<class U> struct error {};
       typedef typename error<T>::type type;
    };
    
    template<class T>
    T& mutate_safely(T const& x)
    {
       return const_cast<T&>(x);
    }
    
    template<class T>
    T& mutate_safely(T& x, typename ConstHelper<T>::type = 0)
    {
       return x;
    }
    //...
    void foo (int&);
    foo (mutate_safely(42));
    

  • Mod

    queer_boy schrieb:

    reicht dir vielleicht sowas?

    template<class T> struct ConstHelper
    {
       typedef int type;
    };
    
    template<class T> struct ConstHelper<T const>
    {
       template<class U> struct error {};
       typedef typename error<T>::type type;
    };
    
    template<class T>
    T& mutate_safely(T const& x)
    {
       return const_cast<T&>(x);
    }
    
    template<class T>
    T& mutate_safely(T& x, typename ConstHelper<T>::type = 0)
    {
       return x;
    }
    //...
    void foo (int&);
    foo (mutate_safely(42));
    

    Das ist auch nur undefiniert auf einem höheren Level. Bei dieser Mine verlierst du nicht bloß den Fuß sondern gleich das ganze Bein. Nebenbei bemerkt, werden auch const-lvalues von der ersten Überladung konsumiert und nicht von der zweiten (1. weil diese spezieller ist und 2. weil die zweite Überladung dann dank SFINAE herausfällt).



  • Ich hab mal einen Bug gegen GCC berichtet:

    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32658


Anmelden zum Antworten