1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
#include <iostream>
#include <utility>
#include <string>
template< typename T, std::size_t N > void assign( T(&arr)[N], std::size_t pos, const T& value )
{ if( pos < N ) arr[pos] = value ; /* copy assign lvalue*/ }
template< typename T, std::size_t N > void assign( T(&arr)[N], std::size_t pos, T&& value )
{ if( pos < N ) arr[pos] = std::move(value) ; /* move assign rvalue*/ }
template< typename T, std::size_t N > void assign_v2( T(&arr)[N], std::size_t pos, T value )
{ if( pos < N ) arr[pos] = std::move(value) ; /* move assign parameter passed by value*/ }
template< typename T, std::size_t N, typename U > void assign_v3( T(&arr)[N], std::size_t pos, U&& value )
{ if( pos < N ) arr[pos] = std::forward<U>(value) ; /* perfect forwarding */ }
struct A
{
A() = default ;
A( const char* cstr ) : str(cstr) {}
A( const A& that ) : str(that.str)
{ std::cout << "copy construct\n" ; }
A( A&& that ) noexcept : str( std::move(that.str) )
{ str.swap(that.str) ; std::cout << "move construct\n" ; }
A& operator= ( const A& that )
{ str = that.str ; std::cout << "copy assign\n" ; return *this ; }
A& operator= ( A&& that ) noexcept
{ str.swap(that.str) ; std::cout << "move assign\n" ; return *this ; }
std::string str ;
};
int main()
{
A arr[20] ; // 20 strings are default-constructed
A hello( "hello" ) ;
assign( arr, 0, hello ) ; // lvalue, copy assign
std::cout << "------------\n" ;
// hello can still be used here
assign( arr, 1, A( " world!" ) ) ; // rvalue, move assign
std::cout << "------------\n\n" ;
assign_v2( arr, 2, hello ) ; // lvalue, copy construct, followed by move assign the copy
std::cout << "------------\n" ;
assign_v2( arr, 3, A( " world!" ) ) ; // rvalue, move assign (copy elision)
std::cout << "------------\n\n" ;
assign_v3( arr, 2, hello ) ; // lvalue, copy assign
std::cout << "------------\n" ;
assign_v3( arr, 3, A( " world!" ) ) ; // rvalue, move assign
std::cout << "------------\n" ;
}
|