头文件
:头文件中定义了固定大小的数组容器array 类和两个函数begin和end。
模板类定义
原型定义
template < class T, size_t N > class array;
类介绍
数组array是一个大小固定的序列容器:容器中保存这特定数量的元素,元素按照严格的线性序列保存。
在容器内部,除了容器的元素不会保存任何其他的数据(甚至大小也不保存,大小是模板类的参数,在编译时确定)。就存储大小而言它与使用括号语法([])声明的数组一样高效。这个类只是在数组的基础上添加了成员函数和全局函数,这样数组就可以当作标准容器来使用。
与其他标准容器不同,array的大小是固定的,而且不会通过一个内存分配器来管理元素内存的分配:它是一个封装了固定数量元素的数组的聚合类型。因此,它不能动态的添加或删除元素(类似的大小可扩展的容器参见vector)。
大小为0的数组是有效的,但是不能对元素进行访问( 成员函数front、back、data)。
与标准库中的其他容器不同,交换两个array的内容,不管是全部交换还是只交换一个范围内的元素(通常效率非常地的操作),时间复杂度都是线性的。同时还使迭代器保留对原始数组的引用。
array的另一个独有的特征是,可以把array当作一个tuple对象来看待:<array>头文件中重载了get函数使array像tuple一样访问元素,还有指定的tuple_size和tuple的元素类型。
容器属性
顺序存储
容器中的元素以严格的线性序列存储。每个元素都可以通过它在序列中的位置来访问。
连续存储
容器的元素保存在一段连续的内存空间中,因此可以以常数时间复杂度来访问任意的元素(O(1))。可以通过使用指向一个元素的指针加上偏移来访问另一个元素。
大小固定
容器使用隐藏构造函数和析构函数来静态的申请和释放内存空间。容器的大小是编译时常量。没有内存或时间开销。
模板参数
T
元素的类型,别名为成员类型array::alue_type。
N
array的大小,元素的数量。
在成员函数中的参数假定与模板参数的名称相同。
成员类型
以下的别名是array的成员类型,他们广泛用于成员函数的参数和返回类型。

成员函数
std::array::begin
函数原型
iterator begin() noexcept;
const_iterator begin() const noexcept;
功能
返回一个指向array容器第一个元素的迭代器。注意:与array::front函数(返回第一个元素的引用)不同,begin返回的是指向第一个元素的可以随机访问的迭代器。
在大小为0的数组中,返回值与array::end相同,但是返回的迭代器不应该解引用来访问元素。
参数
无
返回值
一个指向序列开始的迭代器。如果array是const的,则返回一个const_iterator,否则返回一个iterator。
成员类型iterator和const_iterator都是可以随机访问的(分别指向普通元素和静态的元素)。
Example
// array::begin example
#include <iostream>
#include <array>
int main ()
{
std::array<int,5> myarray = { 2, 16, 77, 34, 50 };
std::cout << "myarray contains:";
for ( auto it = myarray.begin(); it != myarray.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Output:
myarray contains: 2 16 77 34 50
复杂度
常数
迭代器有效性
不会修改迭代器的有效性。
数据竞争
该函数不会访问array的元素,但是返回的迭代器可以访问和修改元素。同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。拷贝构造或在对返回的迭代器赋值都不会抛出异常。
std::array::end
函数原型
iterator end() noexcept;
const_iterator end() const noexcept;
功能
返回一个指向array容器the past-the-end element的迭代器。
the past-the-end element是一个理论上的元素,在array最后一个元素的下一个位置。它不指向任何的元素,因此不能解引用来访问元素。
由于标准库函数访问元素范围不包括终止迭代器指向的元素,因此该函数通常用来与array::begin一起使用来指定容器的元素范围。
在大小为0的数组中,返回值与array::begin相同,但是返回的迭代器不应该解引用来访问元素。
参数
无
返回值
一个指向序列最后一个元素的下一个位置的迭代器。如果array是const的,则返回一个const_iterator,否则返回一个iterator。
成员类型iterator和const_iterator都是可以随机访问的(分别指向普通元素和静态的元素)。
Example
// array::end example
#include <iostream>
#include <array>
int main ()
{
std::array<int,5> myarray = { 5, 19, 77, 34, 99 };
std::cout << "myarray contains:";
for ( auto it = myarray.begin(); it != myarray.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Output:
myarray contains: 5 19 77 34 99
复杂度
常数
迭代器有效性
不会修改迭代器的有效性。
数据竞争
该函数不会访问array的元素,但是返回的迭代器可以访问和修改元素。同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。拷贝构造或在对返回的迭代器赋值都不会抛出异常。
std::array::rbegin和std::array::rend
函数原型
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
功能
rbegin: 返回一个反向的迭代器,指向容器最后一个元素。rbegin指向的元素正好是end函数指向元素的前一个。与另一个成员函数array::back不同,back返回的是指向最后一个元素的引用,而rbegin返回的是同一个元素的迭代器,并且迭代器可以任意访问成员。
rend: 返回一个指向容器第一个元素的前面一个元素的迭代器,该元素只是理论上的元素(该元素被定为为数组的反向结束位置)。rbegin和rend之间包含了容器的所有元素。
参数
无
返回值
rbegin: 一个反向迭代器,该迭代器指向反向第一个元素也就是容器最后一个元素。
rend: 一个指向反向结束位置的反向迭代器。
如果array是const的,则返回的迭代器是const_iterator。否则返回一个正常的迭代器。
成员类型reverse_iterator 和 const_reverse_iterator都是反向可以随机访问的迭代器(分别指向普通元素和const元素)。
Example
// array::rbegin/rend
#include <iostream>
#include <array>
int main ()
{
std::array<int,4> myarray = {4, 26, 80, 14} ;
std::cout << "myarray contains:";
for ( auto rit=myarray.rbegin() ; rit < myarray.rend(); ++rit )
std::cout << ' ' << *rit;
std::cout << '\n';
return 0;
}
Output:
myarray contains: 14 80 26 4
注意: 反向迭代器是反向增长的。
复杂度
常数
迭代器有效性
不会修改迭代器的有效性。
数据竞争
该函数不会访问array的元素,但是返回的迭代器可以访问和修改元素。同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。拷贝构造或在对返回的迭代器赋值都不会抛出异常。
std::array::cbegin和std::array::cend
函数原型
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
功能
cbegin: 返回指向容器第一个元素的const_iterator。const_iterator指向指向的内容是const的。迭代器可以向前和向后移动(除非它本身也是const的)。与array::begin返回的值是相同的,但是不能修改该函数返回的迭代器指向的内容,即使array本身并不是const的。
cend: 返回一个指向容器最后一个元素的下一个位置的const_iterator。与array::end返回的值是相同的,但是不能修改该函数返回的迭代器指向的内容,即使array本身并不是const的。
参数
无
返回值
cbegin: 返回指向容器第一个元素的const_iterator。
cend: 一个指向容器最后一个元素的下一个位置的const_iterator。
成员类型const_iterator是可以随机访问的迭代器类型,指向一个const元素。
Example
// array::cbegin example
#include <iostream>
#include <array>
int main ()
{
std::array<int,5> myarray = { 2, 16, 77, 34, 50 };
std::cout << "myarray contains:";
for ( auto it = myarray.cbegin(); it != myarray.cend(); ++it )
std::cout << ' ' << *it; // cannot modify *it
std::cout << '\n';
return 0;
}
Output:
myarray contains: 2 16 77 34 50
复杂度
常数
迭代器有效性
不会修改迭代器的有效性。
数据竞争
该函数不会访问array的元素,但是返回的迭代器可以访问和修改元素。同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。拷贝构造或在对返回的迭代器赋值都不会抛出异常。
std::array::crbegin和std::array::crend
函数原型
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
功能
功能就不再重复描述了,返回的是const 的反向迭代器。与rbegin与rend的区别就是返回的迭代器不能用来修改元素。
参数
无
返回值
反向的const 迭代器。
Example
// array::crbegin/crend
#include <iostream>
#include <array>
int main ()
{
std::array<int,6> myarray = {10, 20, 30, 40, 50, 60} ;
std::cout << "myarray backwards:";
for ( auto rit=myarray.crbegin() ; rit < myarray.crend(); ++rit )
std::cout << ' ' << *rit; // cannot modify *rit
std::cout << '\n';
return 0;
}
Output:
myarray backwards: 60 50 40 30 20 10
复杂度
常数
迭代器有效性
不会修改迭代器的有效性。
数据竞争
该函数不会访问array的元素,但是返回的迭代器可以访问和修改元素。同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。拷贝构造或在对返回的迭代器赋值都不会抛出异常。
std::array::size
函数原型
constexpr size_type size() noexcept;
功能
返回容器中元素的数量。array的size总是与array类模板的参数N相等。与C++的sizeof不同,sizeof返回的是字节数,该函数返回元素数量。
参数
无
返回值
容器array中元素的数量,这是一个编译时常量。size_type是unsigned integer类型size_t的别名。
Example
// array::size
#include <iostream>
#include <array>
int main ()
{
std::array<int,5> myints;
std::cout << "size of myints: " << myints.size() << std::endl;
std::cout << "sizeof(myints): " << sizeof(myints) << std::endl;
return 0;
}
Possible output:
size of myints: 5
sizeof(myints): 20
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数不会访问array的元素:同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。
std::array::max_size
函数原型
constexpr size_type max_size() noexcept;
功能
返回容器可以保存元素的最大数量。max_size与size一样,永远与array类模板的第二个参数N相等。
参数
无
返回值
容器array可以保存元素的最大数量,这是一个常量。size_type是unsigned integer类型size_t的别名。
Example
// array::max_size
#include <iostream>
#include <array>
int main ()
{
std::array<int,10> myints;
std::cout << "size of myints: " << myints.size() << '\n';
std::cout << "max_size of myints: " << myints.max_size() << '\n';
return 0;
}
Possible output:
size of myints: 10
max_size of myints: 10
size和max_size总是匹配相等的。
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数不会访问array的元素:同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。
std::array::empty
函数原型
constexpr bool empty() noexcept;
功能
返回一个布尔值,来表示容器是不是空的,也就是size是不是0。该函数不会修改容器的内容。清空容器可以使用array::fill方法。
参数
无
返回值
如果size为0则返回True,否则返回false。返回在是常数。
Example
// array::empty
#include <iostream>
#include <array>
int main ()
{
std::array<int,0> first;
std::array<int,5> second;
std::cout << "first " << (first.empty() ? "is empty" : "is not empty") << '\n';
std::cout << "second " << (second.empty() ? "is empty" : "is not empty") << '\n';
return 0;
}
Output:
first is empty
second is not empty
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数不会访问array的元素:同时访问或修改元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。
std::array::operator[]
函数原型
reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
功能
返回array容器在位置n处元素的引用。功能与array::at函数的功能类似,不同的是at函数会检查n是否在有效范围内,超出范围会抛出异常。
参数
n: array中元素的位置。第一个元素从0开始标记。
返回值
指定位置的元素。如果array是const的则返回一个const的引用,否则返回一个普通的引用。成员类型reference和const_reference是指向array元素的引用类型。
Example
// array::operator[]
#include <iostream>
#include <array>
int main ()
{
std::array<int,10> myarray;
unsigned int i;
// assign some values:
for (i=0; i<10; i++) myarray[i]=i;
// print content
std::cout << "myarray contains:";
for (i=0; i<10; i++)
std::cout << ' ' << myarray[i];
std::cout << '\n';
return 0;
}
Output:
myarray contains: 0 1 2 3 4 5 6 7 8 9
复杂度
常数
迭代器有效性
不会变化。
数据竞争
返回的引用可以访问或着修改元素值:同时修改不同的元素是安全的。
异常&安全
如果n小于size,该函数不会抛出异常;否则会导致不确定的行为。
std::array::at
函数原型
reference at ( size_type n );
const_reference at ( size_type n ) const;
功能
返回array容器在位置n处元素的引用。该函数会检查n是否在有效范围内,如果超出范围则抛出out_of_range的异常。相反,operator[]操作符不会检查n的有效性。
参数
n: array中元素的位置。如果大于等于size的话会抛出out_of_range的异常。注意第一个元素从0开始。
返回值
array中指定位置的元素。如果array是const的则返回一个const的引用,否则返回一个普通的引用。成员类型reference和const_reference是指向array元素的引用类型。
Example
// array::at
#include <iostream>
#include <array>
int main ()
{
std::array<int,10> myarray;
// assign some values:
for (int i=0; i<10; i++) myarray.at(i) = i+1;
// print content:
std::cout << "myarray contains:";
for (int i=0; i<10; i++)
std::cout << ' ' << myarray.at(i);
std::cout << '\n';
return 0;
}
Output:
myarray contains: 1 2 3 4 5 6 7 8 9 10
复杂度
常数
迭代器有效性
不会变化。
数据竞争
返回的引用可以访问或着修改元素值:同时修改不同的元素是安全的。
异常&安全
强保证: 如果出现异常,不会修改容器元素。如果n超出有效范围则抛出out_of_range的异常。
std::array::front
函数原型
reference front();
const_reference front() const;
功能
返回容器第一个元素的引用。begin返回的是一个迭代器,而此函数返回一个直接引用。在空容器上调用该函数会导致不确定的行为。
参数
无
返回值
第一个元素的引用。如果array是const的则返回一个const的引用,否则返回一个普通的引用。成员类型reference和const_reference是指向array元素的引用类型。
Example
// array::front
#include <iostream>
#include <array>
int main ()
{
std::array<int,3> myarray = {2, 16, 77};
std::cout << "front is: " << myarray.front() << std::endl; // 2
std::cout << "back is: " << myarray.back() << std::endl; // 77
myarray.front() = 100;
std::cout << "myarray now contains:";
for ( int& x : myarray ) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
Output:
front is: 2
back is: 77
myarray now contains: 100 16 77
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数的返回值可以访问或者修改元素值。同时修改其他元素是安全的。
异常&安全
如果容器不空,不会抛出异常。否则会导致不确定的行为。
std::array::back
函数原型
reference back();
const_reference back() const;
功能
返回容器最后一个元素的引用。end返回的是一个指向最后一个元素下一个位置的迭代器,而此函数返回一个直接引用。在空容器上调用该函数会导致不确定的行为。
参数
无
返回值
最后一个元素的引用。如果array是const的则返回一个const的引用,否则返回一个普通的引用。成员类型reference和const_reference是指向array元素的引用类型。
Example
// array::back
#include <iostream>
#include <array>
int main ()
{
std::array<int,3> myarray = {5, 19, 77};
std::cout << "front is: " << myarray.front() << std::endl; // 5
std::cout << "back is: " << myarray.back() << std::endl; // 77
myarray.back() = 50;
std::cout << "myarray now contains:";
for ( int& x : myarray ) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
Output:
front is: 5
back is: 77
myarray now contains: 5 19 50
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数的返回值可以访问或者修改元素值。同时修改其他元素是安全的。
异常&安全
如果容器不空,不会抛出异常。否则会导致不确定的行为。
std::array::data
函数原型
value_type* data() noexcept;
const value_type* data() const noexcept;
功能
返回指向第一个元素的指针。由于array保存在一个连续的区域内,所以可以使用该指针加上偏移来访问任意的元素。
参数
无
返回值
array元素的指针。如果array是const的,则返回指向 const value_type的指针,否则返回一个普通指针。value_type是容器中元素的数据类型。
Example
// array::data
#include <iostream>
#include <cstring>
#include <array>
int main ()
{
const char* cstr = "Test string";
std::array<char,12> charray;
std::memcpy (charray.data(),cstr,12);
std::cout << charray.data() << '\n';
return 0;
}
Output:
Test string
复杂度
常数
迭代器有效性
不会变化。
数据竞争
该函数不会直接访问array的元素,但是返回的指针可以用来访问和修改元素。同时访问或修改不同的元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。
std::array::fill
函数原型
void fill (const value_type& val);
功能
将array中所有元素的值都设置成val。
参数
val: 要填充的值
返回值
无
Example
// array::fill example
#include <iostream>
#include <array>
int main () {
std::array<int,6> myarray;
myarray.fill(5);
std::cout << "myarray contains:";
for ( int& x : myarray) { std::cout << ' ' << x; }
std::cout << '\n';
return 0;
}
Output:
myarray contains: 5 5 5 5 5 5
复杂度
线性的:与array的size相关
迭代器有效性
不会变化。
数据竞争
所有的数据都会变化
异常&安全
基本保证: 如果抛出异常,容器仍处于有效状态。如果赋值出现异常会抛出对应的异常信息。
std::array::swap
函数原型
void swap (array& x) noexcept(noexcept(swap(declval<value_type&>(),declval<value_type&>())));
功能
与另一个array的内容交换,两个array的数据类型和size必须相同。执行该函数后,该容器的内容与x的内容互换。与其他容器的swap不同,array的swap函数执行时间与size成线性关系。
参数
x: 与该容器类型和size相同的另一个容器。
返回值
无
如果其中一个元素交换出现异常,则会抛出一个异常信息。
Example
// swap arrays
#include <iostream>
#include <array>
int main ()
{
std::array<int,5> first = {10, 20, 30, 40, 50};
std::array<int,5> second = {11, 22, 33, 44, 55};
first.swap (second);
std::cout << "first:";
for (int& x : first) std::cout << ' ' << x;
std::cout << '\n';
std::cout << "second:";
for (int& x : second) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
Output:
first: 11 22 33 44 55
second: 10 20 30 40 50
复杂度
与size成线性关系。
迭代器有效性
迭代器、指针和引用的有效性不会变化。迭代器和指针仍然指向对应容器的位置,值变为swap后的值,但引用的值不会变,指向原来的值。
数据竞争
该容器与x容器的值都被访问和修改了。
异常&安全
如果交换没有发生异常,该函数不会抛出异常。否则基本保证容器仍处于有效状态。
非成员函数重载
std::get (array)
函数原型
template <size_t I, class T, size_t N> T& get (array<T,N>& arr) noexcept;
template <size_t I, class T, size_t N> T&& get (array<T,N>&& arr) noexcept;
template <size_t I, class T, size_t N> const T& get (const array<T,N>& arr) noexcept;
功能
返回第I个元素的引用。重载tuple的get函数是为了像处理tuple一样处理array。为此,头文件还使用定义的适当成员重载tuple_size和tuple_element type。
模板参数
I: array中元素的位置,第一个元素为0。
T: array中元素类型(通常可以从array隐式获得)。
N: array中元素的数量(通常可以从array隐式获得)。
函数参数
arr: 一个array容器。
返回值
array中指定位置元素的引用。
Example
// arrays as tuples
#include <iostream>
#include <array>
#include <tuple>
int main ()
{
std::array<int,3> myarray = {10, 20, 30};
std::tuple<int,int,int> mytuple (10, 20, 30);
std::tuple_element<0,decltype(myarray)>::type myelement; // int myelement
myelement = std::get<2>(myarray);
std::get<2>(myarray) = std::get<0>(myarray);
std::get<0>(myarray) = myelement;
std::cout << "first element in myarray: " << std::get<0>(myarray) << "\n";
std::cout << "first element in mytuple: " << std::get<0>(mytuple) << "\n";
return 0;
}
Output:
first element in myarray: 30
first element in mytuple: 10
复杂度
常数
迭代器有效性
不会变化。
数据竞争
array的第I个元素可能会被访问和修改。同步修改其他元素是安全的。
异常&安全
保证不抛出异常: 该函数永远不会抛出异常。
相关的操作符
前面已介绍
本文详细介绍了C++中的std::array容器,包括其模板定义、成员类型和函数,如begin、end、rbegin、rend、size、front、back、data等。std::array是一个固定大小的序列容器,提供了类似于数组的功能,支持迭代器和常量迭代器,且元素存储在连续的内存空间中。此外,文章还提到了std::array与C++的数组和其它容器的区别,如其大小不可变,以及作为tuple的替代品的特性。

3816

被折叠的 条评论
为什么被折叠?



