c++ - Using fold expressions to print all variadic arguments with newlines inbetween -
the classic example c++17 fold expressions printing arguments:
template<typename ... args> void print(args ... args) { (cout << ... << args); }
example:
print("hello", 12, 234.3, complex<float>{12.3f, 32.8f});
output:
hello12234.3(12.3,32.8)
i'd add newlines output. however, can't find way that, best i've found far:
template<typename ... args> void print(args ... args) { (cout << ... << ((std::ostringstream{} << args << "\n").str())); }
this isn't zero-overhead, constructs temporary ostringstream
each argument.
the following versions don't work either:
(cout << ... << " " << args); error: expression not permitted operand of fold expression
and
(cout << ... << (" " << args)); error: invalid operands binary expression
i understand why last 2 versions don't work. there more elegant solution problem, using fold expressions?
repeat
takes function object f
, , return new function object. return value runs f on each of args. "repeats" f
on each of args.
template<class f> auto repeat( f&& f ) { return [f=std::forward<f>(f)](auto&&...args)mutable{ ( void(f(args)), ... ); }; }
use:
repeat ( [](auto&&x){ std::cout << x << "\n"; } ) ( args... );
this uses fold expressions, indirectly. , honestly, have written in c++14 (just body of repeat
uglier).
we write streamer works <<
"more inline" , use fold expressions directly:
template<class f> struct ostreamer_t { f f; friend std::ostream& operator<<( std::ostream& os, ostreamer_t&& self ) { std::move(self).f(os); return os; } }; template<class f> ostreamer_t<f> ostreamer( f&& f ) { return {std::forward<f>(f)}; }
then use this:
(std::cout << ... << ostreamer([&](auto&& os){ os << " " << args;}));
ostreamer
takes function object. returns object overloads <<
such when pass ostream on left, invokes function object ostream.
no temporary stream created.
Comments
Post a Comment