使用折叠表达式打印所有可变参数,中间用换行符 [英] Using fold expressions to print all variadic arguments with newlines inbetween

查看:28
本文介绍了使用折叠表达式打印所有可变参数,中间用换行符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆