#include <iostream>
using namespace std;

class X {
public: 
    X() { cout<<"  ctor "<<this<<endl; }
    X(const X&) { cout<<"  cpyctor "<<this<<endl; }
    X operator+ (X&&) { return X(); }
    ~X() { cout<<"  dtor "<<this<<endl; }
    X& me() { cout<<"    yes!"<<endl;return *this; } 
};

X f() { return X(); }
X& g(X&x) { return x; }

int main() {
	cout << "case1 - completely safe: "<<endl;
	g(f().me().me().me()).me(); 
	cout << "end case1."<<endl<<endl;
    
	cout << "case2 - hoping for life extension but UB: "<<endl;
	{
	   X x; 
       {
          X& myriskyref = (x + f()).me();   // ouch!!! the temporary was created by operator/function return 
                                            // so no life extension accrdong to 12.2/5 
          cout << "  ...next..."<<endl;
          cout << "  OUCH!! temp already deleted (see above):"<<&myriskyref.me() <<endl;
       } // permanent ref vanisches; 
	}
    cout << "end case2."<<endl<<endl; 
    cout<< "case 3:" <<endl; 
    {
       const X donottouch; 
       //donottouch.me();    would be compilation error 
    }
    cout << "end case 3."<<endl; 
    
	return 0;
}