gpt4 book ai didi

c++ - 可变参数模板查询

转载 作者:行者123 更新时间:2023-12-04 03:24:08 27 4
gpt4 key购买 nike

我试图理解下面的代码。直接从 Jason Turner youtube 视频复制

#include <iostream>
#include <sstream>
#include <vector>

template<typename ...T>
std::vector<std::string> print(const T& ...t)
{
std::vector<std::string> retval;
std::stringstream ss;
(void)std::initializer_list<int>{
(
ss.str(""),
ss << t,
retval.push_back(ss.str()),
0)...
};
return retval;
}

int main()
{
for( const auto &s : print("Hello", "World", 5.4, 1.1, 2.2) ) {
std::cout << s << "\n";
}
}

问题:

  1. 有人可以提供 initializer_list 中代码的扩展 View 吗?我很难想象语句是如何扩展每个参数的? ss.str("")、ss << t 然后 push_back 是否针对包中的每个参数发生,或者它们只执行一次?我无法想象扩展的初始值设定项列表会是什么样子?
  2. 为什么我们需要在 initializer_list 末尾的虚拟“0”?如果我没有那个会怎样?
  3. 如何轻松查看共享代码中的...扩展?

最佳答案

Tt参数包

有两种使用包的主要方式:折叠表达式(在 C++17 和更新版本中)和常规包扩展。

A fold expression看起来像这样:

((ss.str(""), ss << t, retval.push_back(ss.str())), ...);

折叠表达式为每个 pack 元素重复其操作数,在属于每个参数的部分之间插入一些运算符(在本例中为 ,)。上面的扩展为:

((ss.str(""), ss << t1, retval.push_back(ss.str())), // <-- Inserted commas
(ss.str(""), ss << t2, retval.push_back(ss.str())), // <--
(ss.str(""), ss << t3, retval.push_back(ss.str())));

常规扩展类似,只是它总是生成一个逗号,并且该逗号不能是运算符(与数组初始值设定项或函数参数之间的分隔符相反)。 p>

例如如果你写了(ss.str(""), ss << t, retval.push_back(ss.str()))...;在假设它会像折叠表达式一样工作的情况下,它不会工作,因为生成的逗号必须是一个运算符。

由于此限制,在 C++17 之前,人们使用虚拟数组(或您示例中的 initializer_list )。这是使用数组时的样子:

int dummy[] = {(ss.str(""), ss << t, retval.push_back(ss.str()), 0)...};

这扩展为:

int dummy[] = {(ss.str(""), ss << t1, retval.push_back(ss.str()), 0),
(ss.str(""), ss << t2, retval.push_back(ss.str()), 0),
(ss.str(""), ss << t3, retval.push_back(ss.str()), 0)};

此处,数组(或 initializer_list)的大小与包的大小相匹配。

,0是必需的,因为每个数组元素都是一个 int , 所以它必须用 int 初始化.

关于c++ - 可变参数模板查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67973802/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com