如何实现将std::array元素转为std::reference_wrapper数组的模板函数?
最优实现方案:编译期索引序列展开
好问题!要实现这个将std::array元素转换为std::reference_wrapper数组的模板函数,最优的方式是利用C++的编译期元编程特性,完全避免运行时开销,同时严格符合标准规范,且不依赖任何额外容器(比如你提到的vector)。
核心实现代码
#include <array> #include <functional> #include <utility> // 辅助实现函数:利用索引序列展开每个元素的引用包装 template<typename T, size_t N, size_t... Idx> std::array<std::reference_wrapper<T>, N> wrap_impl(std::array<T, N>& a, std::index_sequence<Idx...>) { return {std::ref(a[Idx])...}; } // 对外暴露的接口函数 template<typename T, size_t N> std::array<std::reference_wrapper<T>, N> wrap(std::array<T, N>& a) { return wrap_impl(a, std::make_index_sequence<N>()); }
为什么这是最优解?
- 零运行时开销:借助
std::index_sequence和std::make_index_sequence(C++14起支持),编译器会在编译期直接展开每个元素的std::ref调用,生成目标std::array的初始化列表,完全没有运行时循环或额外函数调用的开销。 - 代码简洁规范:完全基于标准库工具实现,没有手写循环或自定义逻辑,可读性和可维护性拉满。
- 严格符合需求:返回的是
std::array<std::reference_wrapper<T>, N>,和你要求的接口完全一致,且不使用任何vector类容器。
扩展:支持const数组
如果需要处理const std::array,可以重载一个const版本的函数,返回const引用包装器数组:
// const版本的辅助实现 template<typename T, size_t N, size_t... Idx> std::array<std::reference_wrapper<const T>, N> wrap_impl(const std::array<T, N>& a, std::index_sequence<Idx...>) { return {std::cref(a[Idx])...}; } // const版本的对外接口 template<typename T, size_t N> std::array<std::reference_wrapper<const T>, N> wrap(const std::array<T, N>& a) { return wrap_impl(a, std::make_index_sequence<N>()); }
使用示例
#include <iostream> int main() { std::array<int, 3> arr = {1, 2, 3}; auto wrapped_arr = wrap(arr); // 通过包装器修改原数组元素 wrapped_arr[0].get() = 10; std::cout << arr[0] << std::endl; // 输出10 // const数组的使用 const std::array<double, 2> const_arr = {3.14, 2.71}; auto const_wrapped = wrap(const_arr); std::cout << const_wrapped[1].get() << std::endl; // 输出2.71 // const_wrapped[1].get() = 1.0; // 编译错误,符合const语义 return 0; }
内容的提问来源于stack exchange,提问作者ztik
相关产品推荐
相关产品推荐

