#include #include #include #include struct copy_tracker { int v; copy_tracker() : v(0) { std::cout << "copy_tracker::copy_tracker()" << std::endl; } copy_tracker( const copy_tracker& c ) : v( c.v ) { std::cout << "copy_tracker::copy_tracker( const copy_tracker& c )" << std::endl; } copy_tracker( copy_tracker&& c ) : v( c.v ) { std::cout << "copy_tracker::copy_tracker( copy_tracker&& c ) MOVE " << std::endl; } void use_object() { std::cout << v << std::endl; } }; template copy_tracker return_by_value() { return return_by_value(); } template <> copy_tracker return_by_value<1>() { return copy_tracker(); } template copy_tracker return_by_value2() { copy_tracker o = return_by_value2(); o.v = n; return o; } template <> copy_tracker return_by_value2<1>() { copy_tracker o; //return value optimization still applies. o.v = 1; return o; } template copy_tracker static_by_value() { return static_by_value(); } template <> copy_tracker static_by_value<1>() { static copy_tracker o; //return value optimization still applies. return o; } template copy_tracker move_by_value() { return std::move(move_by_value()); } template <> copy_tracker move_by_value<1>() { return copy_tracker(); //return value optimization still applies. } template void pass_by_value(copy_tracker o) { pass_by_value(std::move(o)); // o.v = n; // o.use_object(); } template <> void pass_by_value<1>(copy_tracker o) { o.use_object(); } void test_copy_tracker() { std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Return by value and assign." << std::endl; { copy_tracker o = return_by_value<10>(); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Return by named value and assign." << std::endl; { copy_tracker o = return_by_value2<10>(); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Return static and assign." << std::endl; { copy_tracker o = static_by_value<10>(); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Move value and assign." << std::endl; { copy_tracker o = move_by_value<10>(); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Pass lvalue." << std::endl; { copy_tracker o = return_by_value<10>(); pass_by_value<1>( o ); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Pass by intermediately captured rvalue." << std::endl; { const copy_tracker& o = return_by_value<10>(); pass_by_value<1>( o ); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Pass by intermediately captured rvalue." << std::endl; { const copy_tracker& o = return_by_value<10>(); pass_by_value<1>( static_cast(const_cast(o)) ); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Pass rvalue directly." << std::endl; { pass_by_value<1>( return_by_value<10>() ); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; std::cout << "Pass rvalue directly." << std::endl; { pass_by_value<2>( return_by_value<10>() ); } std::cout << "---------------------------------------------------------" << std::endl << std::endl; } int main ( void ) {try{ test_copy_tracker(); return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; }}