c++ - 使用折叠表达式打印所有带有换行符的可变参数

标签 c++ variadic-templates c++17 fold-expression

C++17 折叠表达式的经典示例是打印所有参数:

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)

我想在我的输出中添加换行符。但是,我找不到一个好的方法来做到这一点,这是迄今为止我发现的最好的方法:

template<typename ... Args>
void print(Args ... args)
{
    (cout << ... << ((std::ostringstream{} << args << "\n").str()));
}

但这不是零开销,因为它为每个参数构造了一个临时的 ostringstream

以下版本也不起作用:

(cout << ... << " " << args);

error: expression not permitted as operand of fold expression

(cout << ... << (" " << args));

error: invalid operands to binary expression 

我明白为什么最后两个版本不起作用。 这个问题有没有更优雅的解决方案,使用折叠表达式?

最佳答案

更新:T.C.下面的评论提供了更好的解决方案:

template<typename ... Args>
void print(Args ... args)
{
    ((cout << args << '\n'), ...);
}

您可以在逗号运算符上使用折叠表达式:

template<typename ... Args>
void print(Args ... args)
{
    ([](const auto& x){ cout << x << "\n"; }(args), ...);
}

用法:

int main()
{
    print("a", 1, 1000);
}

a

1

1000

(注意:这也会打印尾随换行符。)


解释:

  • [](const auto& x){ cout << x << "\n"; }是给定 x 的 lambda版画 x'\n' .

  • [](const auto& x){ cout << x << "\n"; }(args)立即用 args 调用 lambda .

  • ([](const auto& x){ cout << x << "\n"; }(args), ...)逗号运算符 上的折叠表达式,按以下方式扩展:

    // (pseudocode)
    [](const auto& x){ cout << x << "\n"; }(args<0>),
    [](const auto& x){ cout << x << "\n"; }(args<1>),
    [](const auto& x){ cout << x << "\n"; }(args<2>),
    // ...
    [](const auto& x){ cout << x << "\n"; }(args<N>)
    

关于c++ - 使用折叠表达式打印所有带有换行符的可变参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43070062/

相关文章:

c++ - 使用lambda表达式创建线程时,如何为每个线程提供自己的lambda表达式拷贝?

c++ - 有没有办法在不使用 (MFC) 动态对象创建的情况下在 CSplitterWnd 中创建 View ?

javascript - AngularJS 中的 Firebreath 对象

c++ - Switch 语句可变模板扩展

c++ - 生成带有传递给模板的指针类型签名的函数

c++ - 不允许嵌套类的前向声明的原因?

c++ - 空参数包扩展不同于手动空参数包

C++ 为类模板提供初始化列表构造函数

C++ 异步编程,如何不等待 future ?

c++ - Google 测试框架不打印 std::optional