11

在 C++17 中,折叠表达式可用,因此要打印参数,我们可以使用

#define EOL '\n'

template<typename ...Args>
void output_argus(Args&&... args) 
{
    (cout << ... << args) << EOL;
}


int main()
{
    output_argus(1, "test", 5.6f);
}

有输出
1test5.6

如果我想使用折叠表达式'\n'为每个元素附加一个额外的字符来获得以下结果怎么办?

1
test
5.6

这甚至可能吗?如果是,如何?

4

3 回答 3

14

如果我想使用折叠表达式在每个元素上附加一个额外的字符 '\n' 来获得以下结果怎么办?

您可以使用逗号运算符的强大功能

 ((std::cout << args << std::endl), ...);

或者,正如 Quentin 所建议的(谢谢)和你所问的,你可以简单地使用\n而不是std::endl(以避免多次刷新流)

 ((std::cout << args << '\n'), ...); 
于 2018-11-08T22:28:22.297 回答
3

这是@nm 的解决方案,没有粗鲁的全球贪婪operator<<

template<class Os>
struct chain_stream {
  Os& stream;
  template<class Rhs,
    std::enable_if_t<std::is_same_v<Os&, decltype(std::declval<Os&>() << std::declval<Rhs>())>, bool> =true
  >
  friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Rhs&& rhs ) {
    os.stream << std::forward<Rhs>(rhs);
    return os;
  }
  // iomanipulator:
  friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Os&(*rhs)(Os&) ) {
    os.stream << rhs;
    return os;
  }
  template<class Rhs,
    std::enable_if_t<
      std::is_same_v< std::result_of_t< Rhs&&(chain_stream const&) >, void >
      || std::is_same_v< std::result_of_t< Rhs&&(chain_stream const&) >, Os& >,
    bool> =true
  >
  friend chain_stream<Os> const& operator<<( chain_stream<Os> const& os, Rhs&& rhs ) {
    std::forward<Rhs>(rhs)( os );
    return os;
  }
};

现在我们可以这样做:

 (chain_stream{std::cout} << ... << [&](auto& x){x << args << '\n';});

它有效。

于 2018-11-09T01:07:42.147 回答
1

我知道逗号运算符可能是最简单的方法,但为了完整起见,这是我想出的,主要是因为我想炫耀我对 iomanip 的小概括。标准库 iomanips 是函数。有一个<<需要函数指针的重载。我将其扩展到通过引用获取和返回流的任意可调用对象。

template <class Stream, class Func>
auto operator << (Stream& s, Func f) -> 
        std::enable_if_t<std::is_same_v<decltype(f(s)), Stream&>, Stream&>
{
    return f(s);
}

使用我们工具箱中的这个小工具,很容易编写一个折叠表达式,它可以做任何我们想做的事情。

template<typename ...Args>
void output_args(Args&&... args)
{
     (std::cout << ... << [&](auto& x)->auto&{return x << args << '\n';});
}

这种技术可以用于我们需要捕获折叠表达式的值而不是其副作用的场景。在这种情况下,逗号运算符的用处不大。

于 2018-11-08T23:09:40.350 回答