#include <iostream>
using namespace std;

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

X f() { 
	cout<<"               in f"<<endl;
	return X(); }
X& g(X&x) { 
	cout<<"               in g"<<endl;
	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 <<&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;
}