如何在C++列表初始化中展开std::vector实现新vector的拼接初始化
C++ vector初始化列表解包问题解答
核心结论
截至C23标准,C没有原生支持类似Python [11, *tmp1, 99]的列表初始化解包语法,你示例中的std::vector<int> tmp2{11,tmp1,99}无法直接通过编译。
如果要实现同样的效果,有以下几种常用的实现方案:
可选实现方案
方案1:工业界常用的基础写法(兼容所有C++11及以上版本)
不需要任何额外语法支持,可读性和性能都最优:
std::vector<int> tmp1{1,1,2,3,5}; std::vector<int> tmp2; // 提前预分配空间避免多次扩容,提升性能 tmp2.reserve(1 + tmp1.size() + 1); tmp2.push_back(11); // 插入tmp1的所有元素 tmp2.insert(tmp2.end(), tmp1.begin(), tmp1.end()); tmp2.push_back(99);
方案2:自定义辅助函数实现接近一行初始化的效果(兼容C++17及以上版本)
可以写一个通用的vector拼接工具函数:
#include <vector> #include <utility> template<typename T, typename ...Ranges> std::vector<T> join_vectors(std::vector<T> head, Ranges&&... ranges) { // 折叠表达式展开所有待插入的范围 (head.insert(head.end(), std::forward<Ranges>(ranges).begin(), std::forward<Ranges>(ranges).end()), ...); return head; }
使用时的写法非常接近你想要的初始化效果:
std::vector<int> tmp1{1,1,2,3,5}; auto tmp2 = join_vectors(std::vector<int>{11}, tmp1, std::vector<int>{99});
方案3:C++23标准原生范围拼接
C++23引入了std::ranges::concat可以直接拼接多个范围,不需要自定义工具函数:
#include <vector> #include <ranges> int main() { std::vector<int> tmp1{1,1,2,3,5}; auto joined_range = std::ranges::concat(std::views::single(11), tmp1, std::views::single(99)); // 用拼接好的范围直接初始化vector std::vector<int> tmp2(joined_range.begin(), joined_range.end()); return 0; }
补充说明
目前C++标准委员会已有相关提案讨论初始化列表的解包语法,未来的标准版本可能会加入类似Python的原生解包支持,暂时还没有正式落地。
内容的提问来源于stack exchange,提问作者Fady Megally
相关产品推荐
相关产品推荐

