了解这个可变参数模板函数的工作原理

Find out how this variadic templated function works

this answer 中,我看到了一些 C++11 代码,我不太理解(但我想理解)。

在那里,定义了一个可变参数模板函数,它(也许?)获取所有传递的参数并将它们插入到 std::ostringstream 中。

这是函数(请参阅链接答案中的完整工作示例):

template<typename T, typename... Ts>
std::string CreateString(T const& t, Ts const&... ts)
{
    using expand = char[];

    std::ostringstream oss;
    oss << std::boolalpha << t;
    (void)expand{'[=10=]', (oss << ts, '[=10=]')...};
    return oss.str();
}

当我不得不猜测时,我会说,创建了一个字符数组并用 [=13=] 字节初始化,并且将函数的参数插入流中是初始化的副作用(该逗号表达式的一部分)。最后,数组包含的空值与插入流中的项目一样多。它被转换为 void 以避免编译器警告(未使用的变量)。类似这样:

char arr[] = {'[=11=]', (oss << t1, '[=11=]'), (oss << t2, '[=11=]'), ..., (oss << tn, '[=11=]')};

我对这个函数工作原理的描述是否准确?有人可以解释什么设计决策可能与这里相关,以及为什么以这种方式实现它是有益的(我猜替代方案是编译时递归)?

在问题的评论部分收到一些有用的提示后,我可以弄清楚其中的一些要点:

  • 正在使用的功能称为包扩展。它的工作原理与 OP 中描述的完全相同:临时数组使用流插入的副作用进行初始化。可以在此处找到该功能的详细说明:
  • 这是避免递归方法所必需的解决方法,递归方法效率较低。在 C++17 中,不再需要这种解决方法,因为当时引入了 折叠表达式
  • 第一个数组元素已初始化 [=10=] 以避免在仅使用一个参数调用函数时程序格式错误。否则,数组对象将被创建为空的,具有不完整的类型(未知边界的数组),这是非法的。进一步阅读: