/* VIM: let g:lcppflags="-std=c++11 -O2 -pthread" VIM: let g:wcppflags="/O2 /EHsc /DWIN32" VIM: let g:argv="" */ #include #include class copy_tracker { int v; public: 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( copy_tracker& c )" << std::endl; } int use_object() const { return v; } void non_const_method() { v++; std::cout << "copy_tracker::non_const_method()" << std::endl; } }; /* * e */ #if 0 // uncommenting this will cause compiler error due to ambiguity. void e ( copy_tracker o ) { std::cout << "e( ) by value called" << std::endl; o.use_object(); } #endif void e ( copy_tracker& o ) { std::cout << "e( & ) is called" << std::endl; o.use_object(); } void e ( const copy_tracker& o ) { std::cout << "e( const & ) is called" << std::endl; o.use_object(); } void e ( copy_tracker&& o ) { std::cout << "e( && ) is called" << std::endl; o.use_object(); } void e ( const copy_tracker&& o ) { std::cout << "e( const && ) is called" << std::endl; o.use_object(); } /* * f */ void f ( copy_tracker& o ) { std::cout << "f( & ) is called" << std::endl; o.use_object(); } void f ( const copy_tracker& o ) { std::cout << "f( const & ) is called" << std::endl; o.use_object(); } void f ( copy_tracker&& o ) { std::cout << "f( && ) is called" << std::endl; o.use_object(); } /* * g */ void g ( copy_tracker& o ) { std::cout << "g( & ) is called" << std::endl; o.use_object(); } void g ( const copy_tracker& o ) { std::cout << "g( const & ) is called" << std::endl; o.use_object(); } void g ( const copy_tracker&& o ) { std::cout << "g( const && ) is called" << std::endl; o.use_object(); } /* * h */ void h ( copy_tracker& o ) { std::cout << "h( & ) is called" << std::endl; o.use_object(); } void h ( const copy_tracker& o ) { std::cout << "h( const & ) is called" << std::endl; o.use_object(); } /* */ void s( const int & ) { std::cout << "s( const int & ) is called" << std::endl; } void s( int && ) { std::cout << "s( int && ) is called" << std::endl; } /* */ void aaa( const std::string& s ) { std::cout << s << std::endl; } /* * rvalue and const_rvalue */ copy_tracker rvalue() { return copy_tracker(); } const copy_tracker const_rvalue() { return copy_tracker(); } int main( void ) { copy_tracker lvalue; const copy_tracker const_lvalue; // // // std::cout << "The following modifies an rvalue." << std::endl; // rvalue().non_const_method(); // // // std::cout << "e is called for rvalue, const rvalue, lvalue, const lvalue." << std::endl; // e( rvalue() ); e( const_rvalue() ); e( lvalue ); e( const_lvalue ); // // Const rvalue is handled by f( const & ) // std::cout << "f is called for rvalue, const rvalue, lvalue, const lvalue." << std::endl; // f( rvalue() ); f( const_rvalue() );// f( const & ) f( lvalue ); f( const_lvalue ); // // Rvalue is handled by g( const && ) // std::cout << "g is called for rvalue, const rvalue, lvalue, const lvalue." << std::endl; // g( rvalue() );// g( const && ) g( const_rvalue() ); g( lvalue ); g( const_lvalue ); // // Pre C++11 handling. h has only & and const & versions. // std::cout << "h is called for rvalue, const rvalue, lvalue, const lvalue." << std::endl; // h( rvalue() );// h(const &) h( const_rvalue() );// h(const &) h( lvalue ); h( const_lvalue ); // // Try std::move // std::cout << "std::move." << std::endl; // e( std::move(rvalue()) );// e( && ) e( std::move(const_rvalue()) );// e ( const && ) e( std::move(lvalue) );// e( && ) e( std::move(const_lvalue) );// e ( const && ) #if 0 // // The following converts lvalue and const lvalue to rvalue and const // rvalue. // std::cout << "std::forward lvalue and const lvalue." << std::endl; // e( std::forward(rvalue()) );// e( && ) e( std::move(const_rvalue()) );// e ( const && ) e( std::forward(lvalue) );// e( && ) e( std::move(const_lvalue) );// e ( const && ) #endif s( 5 );//s(int &&) aaa( "aaaa"); return 0; }