可变长度std::类似数组
Variable-length std::array like
由于我通常使用的C++编译器允许可变长度的数组(例如,取决于运行时大小的数组),我想知道是否有类似std::array
的可变大小的东西?当然,std::vector
的大小是可变的,但它在堆上进行分配,并在需要时进行重新分配。
我喜欢在运行时定义一个大小为堆栈分配的数组。是否有任何std
-模板可能具有此功能?也许使用具有固定最大大小的std::vector
?
目前有两个建议正在制定中,以将运行时固定大小的数组引入C++,这可能会引起您的兴趣:
-
具有自动存储持续时间的运行时大小的阵列。这将使运行时大小的数组成为一种语言特性(类似于C11)。所以你可以做:
void foo(std::size_t size) { int arr[size]; }
-
C++动态数组。这将为库带来一个新的容器
std::dynarray
,该容器在构建时具有固定的大小。它旨在进行优化,以便在可能的情况下在堆栈上进行分配。void foo(std::size_t size) { std::dynarray<int> arr(size); }
这两个都是作为阵列扩展技术规范的一部分进行的,该技术规范将与C++14一起发布。
更新:std::dyarray尚未实现(2021年8月25日)。请参阅dyarrays的状态如何?
正如Daniel在注释中所说,std::array
的大小被指定为模板参数,因此在运行时无法设置。
您可以通过构造函数参数传递最小容量来构造std::vector
:
#include <vector>
int main(int argc, char * argv[])
{
std::vector<int> a;
a.reserve(5);
std::cout << a.capacity() << "n";
std::cout << a.size();
getchar();
}
但是Still矢量的内容将存储在堆中,而不是堆栈中。问题是,编译器必须知道在函数执行之前应该为其分配多少空间,因此根本不可能在堆栈上存储可变长度的数据。
也许使用具有固定最大大小的
std::vector
?
如果允许升压,那么boost::container::static_vector
和boost::container::small_vector
是我能想到的最接近的
boost::container::static_vector<int, 1024> my_array;
boost::container::small_vector<int, 1024> my_vector;
static_vector
是一个类似于boost::container::vector
的序列容器,具有可以改变大小的连续存储,以及boost::array
的静态分配、低开销和固定容量。
每个对象的大小仍然是固定的,但如果分配数量很大和/或项目计数很小,则这是值得的
如果矢量可以增长超过极限,那么只需使用boost::container::small_vector
。只有当大小大于定义的限制时,才会触摸堆
small_vector
是一个类似向量的容器,针对包含很少元素的情况进行了优化。它包含一些预先分配的元素,当元素的实际数量低于预先分配的阈值时,可以避免使用动态存储分配。
如果您使用Qt,则QVarLengthArray
是另一种方法:
QVarLengthArray
就是试图在C++语言中解决这一差距。它在堆栈上分配一定数量的元素,如果将数组调整为更大的大小,它会自动使用堆。堆栈分配的优点是它比堆分配快得多。示例:
int myfunc(int n) { QVarLengthArray<int, 1024> array(n + 1); ... return array[n]; }
其他一些类似的解决方案:
llvm::SmallVector
- Facebook的
folly::small_vector
- 电子艺术标准模板库的
eastl::fixed_vector
如果不允许3rd方解决方案,那么您可以通过将std::array
封装在结构中来滚动自己的解决方案,以获得静态向量
template<typename T, size_t N>
struct my_static_vector
{
explicit static_vector(size_t size) { } // ...
size_t size() const noexcept { return curr_size; }
static size_t capacity() const noexcept { return N; }
T& operator[](size_t pos) { return data[pos]; }
void push_back(const T& value) { data[curr_size++] = value; }
// ...
private:
std::array<typename T, N> data;
std::size_t curr_size;
}
如果需要small_vector
,则可以使用std::variant
同时包含my_static_vector
和矢量
template<typename T, size_t N>
struct my_small_vector
{
explicit small_vector(size_t size) { } // ...
size_t size() const noexcept {
if (data.index() == 0) {
return data.get<0>().size();
} else {
return data.get<1>().size();
}
}
static size_t capacity() const noexcept {
if (data.index() == 0) {
return data.get<0>().capacity();
} else {
return data.get<1>().capacity();
}
}
// ...
private:
std::variant<my_static_vector<T, N>, std::vector<T>> data;
}
- std::向量与传递值的动态数组
- std::vector的包装器,使数组的结构看起来像结构的数组
- 初始化具有非默认构造函数的std::数组项的更好方法
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 将 int 数组转换为 std::vector<int*>
- 输入std::数组时出现问题
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 为什么std::vector比数组慢
- C++如何生成std::数组列表
- 捕获lambda中的std::数组
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- std::数组边界检查如何工作?
- 通过unique_ptr访问std::数组
- 我正在使用 std::bitset 并尝试创建两个大小为 100,000,000,000 的数组 std::bitset
- 对象的数组-STD ::数组 - 构造函数初始化问题
- 标准::数组<std::array<T、N2>、N> 数据成员上的括号运算符重载
- 从未来对象数组std::vector中检索值
- 如何将动态数组(std::vector)传递给odbc函数SQLBindParameter