, ostringstream ostream, , , , write(std::cout, ...). , ostringstream, , ostringstream . ostringstream void*, .
is_base_of ( , is_convertible).
template<typename Arg, typename... Args, typename =
typename std::enable_if<
!std::is_base_of<
std::ostream,
typename std::remove_reference<Arg>::type,
>::value>::type
>
void write(Arg&& arg, Args&&... args )
{
write( std::cout, std::forward<Arg>(arg), std::forward<Args>(args)... );
}
SFINAE , .
template< typename Arg, typename... Args >
void write_dispatch( std::true_type, Arg&& arg, Args&&... args )
{
std::ostream& os = arg;
write( os, std::forward<Args>(args)... );
}
template< typename Arg, typename... Args >
void write_dispatch( std::false_type, Arg&& arg, Args&&... args )
{
write( std::cout, std::forward<Arg>(arg), std::forward<Args>(args)... );
}
template< typename Arg, typename... Args >
void write( Arg&& arg, Args&&... args )
{
typedef typename std::remove_reference<Arg>::type nonref_type;
write_dispatch( std::is_base_of<std::ostream, nonref_type>(),
std::forward<Arg>(arg), std::forward<Args>(args)... );
}
, - lvalue ostream , write_dispatch, l ostream, write .
out << std::forward<Head>(head), std::forward , lvalues.