VS2017中可变长度数组(VLA)的替代方案有哪些?
刚好我之前也纠结过VS里VLA替代方案的简洁性问题,给你几个实用的思路,完全符合你想要的接近C语言的写法,而且不用折腾new/make_unique或者复杂的容器组合:
方案一:自定义STL风格的模板类型(最推荐)
这个方案类型安全、和STL完全兼容,还能实现你想要的极简语法。我们可以写两个轻量的模板,分别封装一维和二维动态数组:
#include <vector> // 一维动态数组,对应C语言的 int s[n] template<typename T = int> struct arr { // 构造函数:arr s(n) explicit arr(size_t size) : data(size) {} // 重载[]运算符,像普通数组一样访问 T& operator[](size_t idx) { return data[idx]; } const T& operator[](size_t idx) const { return data[idx]; } // 兼容STL的常用方法,比如获取长度 size_t size() const { return data.size(); } auto begin() { return data.begin(); } auto end() { return data.end(); } private: std::vector<T> data; }; // 二维动态数组,对应C语言的 int p[m][3] template<typename T = int> struct mat { // 构造函数:mat p(rows, cols) mat(size_t rows, size_t cols) : data(rows, std::vector<T>(cols)) {} // 重载[]运算符,支持 p[i][j] 访问 std::vector<T>& operator[](size_t row) { return data[row]; } const std::vector<T>& operator[](size_t row) const { return data[row]; } // 获取行列数 size_t rows() const { return data.size(); } size_t cols() const { return data.empty() ? 0 : data[0].size(); } auto begin() { return data.begin(); } auto end() { return data.end(); } private: std::vector<std::vector<T>> data; };
使用示例
#include <iostream> using namespace std; // 上面的arr和mat模板放在这里或者头文件里 int main() { int n; cin >> n; arr s(n); // 等价于原代码的 int s[n] mat p(2 * (n - 1), 3); // 等价于原代码的 int p[2*(n-1)][3] // 像普通数组一样使用 s[0] = 100; p[1][2] = 200; cout << s[0] << endl; cout << p[1][2] << endl; return 0; }
这个方案的好处是完全类型安全,支持任意元素类型(比如arr<double> s(n)),还能直接用STL的算法(比如sort(s.begin(), s.end()))。
方案二:宏定义(快速实现极简语法)
如果你不想写模板,宏定义可以快速实现你想要的简洁写法,缺点是类型安全性稍差,但对于简单场景足够用:
#include <vector> // 一维数组宏,默认int类型 #define ARR(n) std::vector<int>(n) // 二维数组宏,默认int类型 #define MAT(rows, cols) std::vector<std::vector<int>>((rows), std::vector<int>(cols)) // 如果需要支持其他类型,可以写带类型参数的宏: #define ARR_T(T, n) std::vector<T>(n) #define MAT_T(T, rows, cols) std::vector<std::vector<T>>((rows), std::vector<T>(cols))
使用示例
#include <iostream> using namespace std; int main() { int n; cin >> n; auto s = ARR(n); // 等价于 vector<int> s(n); auto p = MAT(2 * (n - 1), 3); // 等价于 vector<vector<int>> p(2*(n-1), vector<int>(3)); // 支持其他类型的用法 auto d_arr = ARR_T(double, 5); d_arr[0] = 3.14; return 0; }
注意:宏没有作用域,建议给宏加前缀避免命名冲突(比如MY_ARR),而且带类型的宏写法不如模板优雅,适合快速测试场景。
避坑提醒:不要用栈上动态分配
VS有一个_alloca扩展可以在栈上分配动态内存,但栈空间有限(通常只有几MB),如果输入的n较大很容易导致栈溢出,完全不推荐用于实际代码。
内容的提问来源于stack exchange,提问作者DuckQueen
相关产品推荐
相关产品推荐

