基于现有std::array的指定索引范围创建新数组的高效方法
当然可以!不用手动循环也能高效实现
完全不需要手动写for循环来复制,C++标准库提供了几种更简洁且高效的方法,这些方法通常会被编译器优化到比手动循环更好的性能(比如利用SIMD指令或批量内存复制)。下面是几种常用方案:
1. 利用迭代器范围直接构造新数组
std::array支持通过迭代器范围来构造,只要目标数组的大小和你要提取的元素数量完全匹配就行。注意迭代器范围是左闭右开的,所以要提取索引2到5的元素(对应值3、4、5、6),结束迭代器要指向索引6的位置:
#include <array> int main() { std::array<int,8> foo = {1,2,3,4,5,6,7,8}; // 从foo的第2个元素开始,到第6个元素前结束(共4个元素) std::array<int,4> bar(foo.begin() + 2, foo.begin() + 6); // bar现在就是{3,4,5,6} return 0; }
2. 使用std::copy_n(C++11及以上)
如果你需要更明确地指定复制的元素数量,可以用std::copy_n,它从起始位置开始复制指定个数的元素到目标容器:
#include <array> #include <algorithm> // 包含std::copy_n int main() { std::array<int,8> foo = {1,2,3,4,5,6,7,8}; std::array<int,4> bar; // 从foo.begin()+2开始,复制4个元素到bar的起始位置 std::copy_n(foo.begin() + 2, 4, bar.begin()); return 0; }
3. C++20范围库(更直观的索引切片)
如果你用的是C++20或更高版本,可以用std::views::slice直接通过索引范围获取子视图,再复制到新数组,代码可读性更强:
#include <array> #include <algorithm> #include <ranges> // 包含std::views::slice int main() { std::array<int,8> foo = {1,2,3,4,5,6,7,8}; std::array<int,4> bar; // slice(起始索引, 结束索引),同样是左闭右开 std::ranges::copy(foo | std::views::slice(2, 6), bar.begin()); return 0; }
为什么这些方法比手动循环高效?
标准库的算法(比如std::copy、std::copy_n)都是经过编译器高度优化的实现,很多情况下会被编译成批量内存复制指令(比如x86的memcpy)或者SIMD指令,比手动写的for循环更高效——尤其是当数组元素数量较多时,这种优化的差距会更明显。
内容的提问来源于stack exchange,提问作者MistyD
相关产品推荐
相关产品推荐

