首页 > 解决方案 > 如何使用折叠表达式扩展为初始化列表?

问题描述

我想在向量中插入与可变参数模板函数的参数一样多的零(即向量中的参数数量为零)。我正在尝试使用折叠表达式来实现这一点,并且在使用(vec.push_back(zeroHelper(args)), ...);.

我不明白的是:为什么当我尝试通过“展开”到初始化器列表中直接初始化向量时它不起作用,如下所示:
std::vector<int> vec = { (zeroHelper(args), ...) };

完整源代码:

template <typename T>
T zeroHelper (T a) { return T{0}; }

template<typename ...Args>
void printer(Args&&... args) {
    std::vector<int> vec; // = { (zeroHelper(args), ...) };
    (vec.push_back(zeroHelper(args)), ...);
    for (auto i : vec) {
        std::cout << i << '\n';
    }
}

int main()
{
    printer(1, 2, 3, 4);
    return 0;
}

这是 OnlineGDB 上的源代码。

预期输出:

0
0
0
0

使用初始化列表方法输出:

0

为什么?

标签: c++c++17variadic-templatesfold-expression

解决方案


因为在

std::vector<int> vec = { (zeroHelper(args), ...) };

括号只返回一个元素,最后一个;逗号运算符丢弃前面的内容。

你应该写

std::vector<int> vec = { zeroHelper(args) ... };

维护所有元素。

(vec.push_back(zeroHelper(args)), ...);

括号激活折叠,逗号丢弃除最后一个之外的所有元素,但该push_back()操作适用vec于每个args...元素。

zeroHelper()还要注意,使用逗号运算符的丢弃特性,您根本不需要

你可以写

std::vector<int> vec { ((void)args, 0)... };

或者

(vec.push_back(((void)args, 0)), ...);

推荐阅读