如何实现返回类型随参数数量变化的C++成员函数magicGet()
实现可变维度嵌套vector的magicGet函数
核心思路
借助C++可变参数模板与递归模板元编程,根据传入的std::size_t参数个数自动生成对应层数的嵌套std::vector类型,再通过递归构造完成各层容器的初始化。
步骤实现
- 定义嵌套vector类型生成器
通过递归模板结构体,根据参数个数生成N层嵌套的vector类型:
#include <vector> #include <type_traits> #define vec std::vector // 递归模板元函数,生成嵌套vector类型 template<typename T, size_t... Dims> struct nested_vec; // 递归终止:无额外维度时返回基础类型T template<typename T> struct nested_vec<T> { using type = T; }; // 递归展开:每层嵌套一层vector template<typename T, size_t Dim, size_t... Dims> struct nested_vec<T, Dim, Dims...> { using type = vec<typename nested_vec<T, Dims...>::type>; }; // 类型别名简化使用 template<typename T, size_t... Dims> using nested_vec_t = typename nested_vec<T, Dims...>::type;
- 实现递归构造函数
编写递归函数,根据传入的维度参数逐层构造嵌套vector:
// 递归终止:构造基础类型实例 template<typename T> T build_nested_vec() { return T{}; } // 递归展开:构造当前层vector,并为每个元素递归构造下一层 template<typename T, size_t FirstDim, size_t... RestDims> vec<typename nested_vec<T, RestDims...>::type> build_nested_vec(size_t first_dim, size_t... rest_dims) { vec<typename nested_vec<T, RestDims...>::type> current_layer(first_dim); for (auto& elem : current_layer) { elem = build_nested_vec<T>(rest_dims...); } return current_layer; }
- 在结构体A中添加magicGet成员函数
将上述逻辑整合到结构体A中,提供对外调用入口:
struct A { // 原有的重载get函数示例 template<typename T> vec<T> get() { return vec<T>{}; } template<typename T> vec<vec<T>> get(size_t d1) { return vec<vec<T>>(d1); } template<typename T> vec<vec<vec<T>>> get(size_t d1, size_t d2) { return vec<vec<vec<T>>>(d1, vec<vec<T>>(d2)); } // 目标magicGet函数:接收任意个size_t参数,返回对应层数的嵌套vector template<typename T, typename... SizeTs> auto magicGet(SizeTs... dims) -> nested_vec_t<T, SizeTs...> { static_assert((std::is_same_v<SizeTs, std::size_t> && ...), "magicGet仅接受std::size_t类型参数"); return build_nested_vec<T>(dims...); } };
使用示例
#include <iostream> int main() { A a; // 传入3个维度参数,得到3层嵌套vector auto vec3d = a.magicGet<int>(2, 3, 4); // 验证维度:外层size=2,中层size=3,内层size=4 std::cout << vec3d.size() << "\n"; // 输出2 std::cout << vec3d[0].size() << "\n"; // 输出3 std::cout << vec3d[0][0].size() << "\n"; // 输出4 return 0; }
注意事项
- 该实现依赖C11及以上标准,C17可通过折叠表达式进一步简化类型生成逻辑;
static_assert用于强制参数类型为std::size_t,避免非法调用;- 若原有
get重载已实现各维度构造逻辑,也可在magicGet中通过参数转发调用对应重载,但递归构造方式更通用,无需维护大量重载函数。
内容的提问来源于stack exchange,提问作者user2961927
相关产品推荐
相关产品推荐

