使用折叠表达式打印所有可变参数,中间用换行符 [英] Using fold expressions to print all variadic arguments with newlines inbetween
问题描述
C ++ 17折叠表达式的经典示例是打印所有参数:
The classic example for C++17 fold expressions is printing all arguments:
template<typename ... Args>
void print(Args ... args)
{
(cout << ... << args);
}
示例:
print("Hello", 12, 234.3, complex<float>{12.3f, 32.8f});
输出:
Hello12234.3(12.3,32.8)
我想在输出中添加换行符.但是,到目前为止,我还没有找到最好的方法来做到这一点:
I'd like to add newlines to my output. However, I can't find a good way to do that, the best I've found so far:
template<typename ... Args>
void print(Args ... args)
{
(cout << ... << ((std::ostringstream{} << args << "\n").str()));
}
但这并不是零开销,因为它为每个参数构造了一个临时的 ostringstream
.
This however isn't zero-overhead, as it constructs a temporary ostringstream
for each argument.
以下版本也不起作用:
(cout << ... << " " << args);
error: expression not permitted as operand of fold expression
还有
(cout << ... << (" " << args));
error: invalid operands to binary expression
我了解为什么最后两个版本不起作用.使用折叠表达式是否可以解决此问题?
I understand why the last two versions don't work. Is there a more elegant solution to this problem, using fold expressions?
推荐答案
repeat
接受一个函数对象 f
,并返回一个新的函数对象.返回值在其每个arg上运行f.它会在每个参数上重复" f
.
repeat
takes a function object f
, and return a new function object. The return value runs f on each of its args. It "repeats" f
on each of its args.
template<class F>
auto repeat( F&& f ) {
return [f=std::forward<F>(f)](auto&&...args)mutable{
( void(f(args)), ... );
};
}
使用:
repeat
( [](auto&&x){ std::cout << x << "\n"; } )
( args... );
这使用折叠表达式,但仅间接使用.老实说,您可能是用C ++ 14编写的(只是 repeat
的正文比较难看).
This uses fold expressions, but only indirectly. And honestly, you could have written this in C++14 (just the body of repeat
would be uglier).
我们还可以编写一个与<<
一起使用的流媒体,使其更加内联"并直接使用折叠表达式:
We could also write a streamer that works with <<
to do it "more inline" and 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 we use it like this:
(std::cout << ... << ostreamer([&](auto&& os){ os << " " << args;}));
ostreamer
带有一个功能对象.它返回一个重载<<
的对象,这样当您向其传递左侧的ostream时,它将使用ostream调用函数对象.
ostreamer
takes a function object. It returns an object that overloads <<
such that when you pass it an ostream on the left, it invokes the function object with the ostream.
没有创建临时流.
实时示例.
这篇关于使用折叠表达式打印所有可变参数,中间用换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!