【问题标题】:Sending a template parameter pack to std::basic_ostream将模板参数包发送到 std::basic_ostream
【发布时间】:2020-06-08 10:02:43
【问题描述】:

cppreference page 上有一个用于std::integer_sequence 的代码示例:

template<typename T, T... ints>
void print_sequence(std::integer_sequence<T, ints...> int_seq)
{
    std::cout << "The sequence of size " << int_seq.size() << ": ";
    ((std::cout << ints << ' '),...);
    std::cout << '\n';
}

我不太了解((std::cout &lt;&lt; ints &lt;&lt; ' '),...) 语法。我没有看到任何会采用可变参数模板的参数包的 std::basic_ostream::operator

这里到底发生了什么,它是如何工作的?

【问题讨论】:

    标签: c++ stl c++14 variadic-templates ostream


    【解决方案1】:

    我不太了解((std::cout &lt;&lt; ints &lt;&lt; ' '),...) 语法。我没有看到std::basic_ostream::operator&lt;&lt; 的任何重载版本会采用可变参数模板的参数包。

    这里到底发生了什么,它是如何工作的?

    如果我没记错的话,它叫做"fold expression",但你也可以找到它作为“模板折叠”或简称为“折叠”。

    从 C++17 开始提供。

    这个想法是在可变参数包上应用一个运算符。

    经典例子:总和。

    如果您想要ints 的总和,您可以应用+ 运算符,如下所示

    ( ints + ... );
    

    在您的情况下,折叠表达式应用于逗号运算符。

    所以,如果ints... 是(例如)2, 3, 5, 7,你的表达式:

    ((std::cout << ints << ' '),...);
    

    等价于

    (std::cout << 2 << ' '), (std::cout << 3 << ' '), (std::cout << 5 << ' '), (std::cout << 7 << ' ');
    

    【讨论】:

      【解决方案2】:

      operator&lt;&lt; 不需要接受可变参数包即可。这里实际发生的情况是,例如,对于 3 个整数,该行将以如下方式扩展:

      (
        (std::cout << int1 << ' '),
        (std::cout << int2 << ' '),
        (std::cout << int3 << ' ')
      );
      

      运算符, 保证执行顺序是从左到右。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-11
        • 1970-01-01
        • 2018-03-03
        相关资源
        最近更新 更多