c++26新功能—inplace_vector
一、inplace_vector
inplace_vector,看上去有些古怪,在前面的标准库中,已经有了std::array和std::vector,为什么在标准库中又设计一个inplace_vector?只有一个原因,实际的应用场景有需要。比如在嵌入式系统中,开发者可能需要vector的一些灵活的操作但又不愿意二次动态扩展,使用数组又有可能无法控制数组动态的大小(比如在范围内的动态增减,需要手动进行标记和识别,移动等)。
或者可以这样理解,可能需要一个数据处理量不大(不需要动态分配内存),但应用又可以自动管理自身数据内容的容器即类似于std::vector与std::array二者之间的一种容器。这样既有了数组的效率又有了向量的灵活。当然,这种容器应用的场景也被限定了,只能是小数据量情况下,一般会在K级内。
所以在C++26中就推出了这个std::inplace_vector,用来实现上述的这种应用场景,需要说明的是,它分配的栈空间上,容量固定,大小可变,在处理小数据量时优势更明显。
二、与std::array和std::vector的比较
既然分析了std::inplace_vector,那么std::inplace_vector与std::array和std::vector的具体的区别有哪些呢?
1、std::vector分配在堆空间上,而其它两个分配在栈空间上
2、std::vector在运行时大小容量可变化(二次分配),但在其它两个容器在编译时则已经固定容量
3、std::array的大小是不可变的,即大小和容量保持一致;而其它两个大小可变(即容量和大小分离),不过std::inplace_vector大小只能固定的容量范围内变化
4、std::vector可能在运行时再次进行容量的扩展,其它两个容器则永远不会
5、std::array没有异常处理,而其它两个都存在异常处理的情况
三、应用场景
std::inplace_vector的特点就是其应用的场景的特点,或者说是应用的需求特点确定了std::inplace_vector的特点。从此处可以看出std::inplace_vector的应用场景:
1、嵌入式和低功耗的设备
一般无法或很少动态分配内存,主要是为了提高处理效率,提高访问速度
2、对延时控制要求很高的场景
比如实时系统或高频交易,毕竟std::inplace_vector在栈上操作也不进行二次扩展
3、需要在某些需要动态调整大小的场景下
比如在常量求值期骨需要动态处理数组的大小的情况
四、例程
看一下官网相关的例程:
#include <algorithm>
#include <array>
#include <cassert>
#include <inplace_vector>int main()
{std::inplace_vector<int, 4> v1{0, 1, 2};assert(v1.max_size() == 4);assert(v1.capacity() == 4);assert(v1.size() == 3);assert(std::ranges::equal(v1, std::array{0, 1, 2}));assert(v1[0] == 0);assert(v1.at(0) == 0);assert(v1.front() == 0);assert(*v1.begin() == 0);assert(v1.back() == 2);v1.push_back(3);assert(v1.back() == 3);assert(std::ranges::equal(v1, std::array{0, 1, 2, 3}));v1.resize(3);assert(std::ranges::equal(v1, std::array{0, 1, 2}));assert(v1.try_push_back(3) != nullptr);assert(v1.back() == 3);assert(v1.size() == 4);assert(v1.try_push_back(13) == nullptr); // no placeassert(v1.back() == 3);assert(v1.size() == 4);v1.clear();assert(v1.size() == 0);assert(v1.empty());
}
这个代码还是非常简单的,就不做具体分析了。有兴趣的可以详细的用相关工具进行对比分析,就能更好的理解此容器的应用。
五、总结
越看标准的演进,越可以发现,标准真的是一边向其它高级语言对齐一些优秀的应用特点;另外一边还要不停的把缺失的应用场景不断的补齐。std::inplace_vector就是典型的一种情况,其实这种场景下,直接用数组操作然后再做一些处理也可以达到类似的效果。可如果标准库中有的话,大家肯定更乐意使用标准库的容器。
一面不断创新,一面不断完善,这就是标准的强大之处。