#include <iostream>
struct A
{
A( int ii ) : i(ii) { std::cout << "constructor i == " << i << '\n' ; }
A( const A& that ) : i(that.i)
{ std::cout << "copy constructor i == " << i << '\n' ; }
~A() { std::cout << "destructor i == " << i << '\n' ; }
A& operator= ( const A& that )
{ i = that.i ; std::cout << "copy assignment i == " << i << '\n' ; return *this ; }
int i ;
};
A operator+ ( const A& a, const A& b )
{
A temp( a.i + b.i ) ; // RVO applies, constructing 'temp'
return temp ; // and then copying temp is elided
// the function directly constructs the return value, 'temp' is elided
}
int main()
{
A a(6) ; // constructor i == 6
A b(8) ; // constructor i == 8
A c(0) ; // constructor i == 0
std::cout << "------------------------------\n" ;
c = a+b ; // call operator+(a,b), RVO applies
// step one:
// construct anonymous temporary 'in place' - constructor i == 14
// no copy or move constructor is involved
// step two:
// assign the anonymous temporary returned by operator+ to c
// assignment i == 14
// step three:
// destroy the anonymous temporary returned by operator+
// destructor i == 14
std::cout << "------------------------------\n" ;
a.i = 100 ;
b.i = 56 ;
A d = a+b ; // call operator+(a,b), RVO applies
// this function returns a prvalue ("pure rvalue")
// a prvalue need not be associated with any object, it can be elided
// therefore, construct d 'in place'
// construct d - constructor i == 156
// no copy or move constructor is involved
std::cout << "------------------------------\n" ;
std::cout << "press enter to destroy 'a', 'b', 'c' and 'd' and then quit\n" ;
std::cin.get() ;
// destroy d - destructor i == 156
// destroy c - destructor i == 14
// destroy b - destructor i == 56
// destroy a - destructor i == 100
}