超详细STL之array容器使用及实现原理解析

说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。

本篇文章讲述STL中array的使用及原理。

导读

array其实是一个固定大小的数组,元素类型及大小在声明的时候指定,原型如下:

template<typename _Tp, std::size_t _Nm>
    struct array
    {
    ...
    };

有些书上说array也是一个class,但是我这个版本看到的是struct,不过没有关系,除了一些细微的方面,struct和class并无太大的区别,这里可以看到array其实就是一个模板类。

array的初步使用

使用array要包含头文件<array>,并声明std命名空间才可使用。

如下是一个简单的案例:

#include <array>
#include <iostream>

int main()
{
	std::array<int,5> a = {1,2,3,4,5};
	for(auto i:a)
	{
		std::cout << "value is " << i << std::endl;
	}
	return 0;
}
fill()和swap()的使用

先看下他们的原型,如下:

//fill函数是把当前array里面所有元素都填充为入参__u
void fill(const value_type& __u);
//swap是交换两个array数据
void swap(array& __other) noexcept(_AT_Type::_Is_nothrow_swappable::value);

看一下使用案例:

#include <array>
#include <iostream>

int main()
{
	std::array<int,5> arr1;
	arr1.fill(5);
	for(auto i:arr1)
	{
		std::cout << "arr1 value is " << i << std::endl;
	}
	std::array<int,5> arr2 = {1,2,3,4,5};
	arr2.swap(arr1);
	for(auto i:arr1)
	{
		std::cout << "arr1 value is " << i << std::endl;
	}
	for(auto i:arr2)
	{
		std::cout << "arr2 value is " << i << std::endl;
	}
	return 0;
}

这里要注意的一个点是,arr1和arr2的元素类型和大小都必须要完全一致,才可以使用swap函数,因为使用swap的前提就是类型要完全一致,而array容器的类型是包括两个模板参数:元素类型和元素个数,如果不一致,编译时没有办法通过的。

迭代器函数
//这里value_type就是定义一个array时指定的元素类型,比如在上面的例子中,它就是int类型
typedef value_type*          		      iterator;
typedef const value_type*			      const_iterator;
//返回一个指向当前array的第一个元素的可读可写的迭代器
_GLIBCXX17_CONSTEXPR iterator
begin() noexcept
{ return iterator(data()); }
//返回一个指向当前array的第一个元素的只读迭代器
_GLIBCXX17_CONSTEXPR const_iterator
begin() const noexcept
{ return const_iterator(data()); }
//返回一个指向当前array的最后一个元素的下一个位置的可读可写迭代器
_GLIBCXX17_CONSTEXPR iterator
end() noexcept
{ return iterator(data() + _Nm); }
//返回一个指向当前array的最后一个元素的下一个位置的只读迭代器
_GLIBCXX17_CONSTEXPR const_iterator
end() const noexcept
{ return const_iterator(data() + _Nm); }
//返回一个指向当前array的最后一个元素的下一个位置的可读可写反转迭代器,也就是指向最后一个元素
_GLIBCXX17_CONSTEXPR reverse_iterator
rbegin() noexcept
{ return reverse_iterator(end()); }
//返回一个指向当前array的最后一个元素的只读迭代器
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rbegin() const noexcept
{ return const_reverse_iterator(end()); }
//返回一个指向当前array的第一个元素的前一个位置的可读可写的迭代器
_GLIBCXX17_CONSTEXPR reverse_iterator
rend() noexcept
{ return reverse_iterator(begin()); }
//返回一个指向当前array的第一个元素的前一个位置的只读迭代器
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rend() const noexcept
{ return const_reverse_iterator(begin()); }

//以下四个迭代器其实与上面的一致,只是它都是只读迭代器
_GLIBCXX17_CONSTEXPR const_iterator
cbegin() const noexcept
{ return const_iterator(data()); }

_GLIBCXX17_CONSTEXPR const_iterator
cend() const noexcept
{ return const_iterator(data() + _Nm); }

_GLIBCXX17_CONSTEXPR const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(end()); }

_GLIBCXX17_CONSTEXPR const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(begin()); }

在这一堆迭代器函数里面有两点需要注意:

  • 一是同样的函数可以返回可读可写和只读两种,比如begin,同样的函数名和参数,只是返回类型和const属性不一样;
  • 二是反转迭代器反转一下其实是指向当前位置的前一个元素的迭代器,也就是说除了位置反转了,其实方向也反转了;

为了避免混淆,使用的时候,如果要可读可写,就直接使用begin,要只读就使用cbegin,要反转的话,就使用rbegin。

使用案例如下:

#include <iostream>
#include <array>
using namespace std;

int main()
{
   
	array<int,5> a = {
   1,2,3,4,5
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp加油站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值