mq卢瑟的作业如下:
首先作业题目是:
// 说出以下代码使用的折叠表达式语法,以及它的效果,详细解析,使用 Markdown 语法。
template<class ...Args>
auto Reverse(Args&&... args) {
std::vector<std::common_type_t<Args...>> res{};
bool tmp{ false };
(tmp = ... = (res.push_back(args), false));
return res;
}
假设 main 函数按照下面方式调用 Reverse 函数:
auto arr = Reverse(1.1, 3);
对于代码 std::vector<std::common_type_t<Args...>> res{};
,解释如下:
01函数模板.md
中讲过" std::common_type_t 的作用很简单,就是确定我们传入的共用类型,说白了就是这些东西都能隐式转换到哪个,那就会返回那个类型。" 所以,根据我main函数中传入的"1.1,3",这里res的类型是std::vector<double>
对于代码 (tmp = ... = (res.push_back(args), false));
,解释如下:
... 在 形参包左侧,所以这是一个二元左折叠表达式,根据下面的展开方式:
((((I 运算符 E1) 运算符 E2) 运算符 ...) 运算符 EN)
实例化展开后是这样:
std::vector<double> Reverse(double && args0, int && args1)
{
std::vector<double> res = std::vector<double>{};
bool tmp = {false};
(tmp = (res.push_back(args0) , false)) = (res.push_back(args1) , false);
return res;
}
注:这里的
tmp
纯属是为了创造一个符合语法的折叠表达式展开效果,它本身并没有什么其他意义。
根据:
loserhomework 的卢瑟日经 赋值运算符求值问题 中提到的:
每个简单赋值表达式 E1 = E2 和每个复合赋值表达式 E1 @= E2 中,E2 的每个值计算和副作用都按顺序早于 E1 的每个值计算和副作用。
(tmp = (res.push_back(args0) , false)) = (res.push_back(args1) , false);
这条语句可以看成是 E1 = E2 类型的赋值表达式。其中:
E1 是 (tmp = (res.push_back(args0) , false))
E2 是 (res.push_back(args1) , false)
因此 E2 : (res.push_back(args1) , false)
先被计算。
注意,这是一个逗号表达式,根据"逗号表达式是从左往右执行的,返回最右边的值作为整个逗号表达式的值",所以 args1 会先被 push_back 到 res 这个容器中,然后返回 false 。
对于 E1 : (tmp = (res.push_back(args0) , false))
,它也可以看成是 E1 = E2 类型的赋值表达式,同上。
所以容器中的元素顺序是:3 , 1.1。
所以该函数是将传入的参数进行逆序。