用C++声明数组

Ast*_*oom 16 c++ arrays stl c++11

我是C++的新手,目前正在自己​​学习一本书.这本书似乎说有几种数组取决于你如何声明它.我想动态数组和静态数组之间的区别对我来说很清楚.但我不明白STL std::array类和静态数组之间的区别.

STL std::array变量声明为:

std::array < int, arraySize > array1;
Run Code Online (Sandbox Code Playgroud)

而静态数组变量声明为:

int array1[arraySize];
Run Code Online (Sandbox Code Playgroud)

这两者之间有根本的区别吗?或者它只是语法而两者基本相同?

vso*_*tco 23

std::array<>只是围绕C风格的阵列的光的包装,具有一些附加漂亮的界面的成员函数(如begin,end等)和typedefS,一个粗略的定义

template<typename T, size_t N>
class array
{
public:
    T _arr[N];
    T& operator[](size_t);
    const T& operator[](size_t) const;
    // other member functions and typedefs
}
Run Code Online (Sandbox Code Playgroud)

但是一个基本的区别是前者可以通过值传递,而后者只能传递指向其第一个元素的指针,或者您可以通过引用传递它,但是您不能将它复制到函数中(除非通过a std::copy或手动) .

一个常见的错误是假设每次将C样式数组传递给函数时,由于数组衰减为指针而导致其大小丢失.这并非总是如此.如果您通过引用传递它,则可以恢复其大小,因为在这种情况下没有衰减:

#include <iostream>

template<typename T, size_t N>
void f(T (&arr)[N]) // the type of arr is T(&)[N], not T*
{
    std::cout << "I'm an array of size " << N;
}

int main()
{
    int arr[10];
    f(arr); // outputs its size, there is no decay happening
}
Run Code Online (Sandbox Code Playgroud)

Live on Coliru


Ste*_*ult 8

这两者之间的主要区别是重要的.

除了STL给你的好方法,当传递std::array给函数时,没有衰减.意思是,当你std::array在函数中收到它std::array时,它仍然是一个,但是当你将一个int[]数组传递给一个函数时,它会有效地衰减到一个int*指针并且数组的大小会丢失.

这种差异是一个重要的差异.一旦丢失了数组大小,代码现在容易出现很多错误,因为您必须手动跟踪数组大小. sizeof()返回指针类型的大小,而不是数组中元素的数量.这会强制您使用类似的接口手动跟踪数组大小process(int *array, int size).这是一个很好的解决方案,但容易出错.

请参阅Bjarne Stroustroup的指南:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-run-time

这可以通过更好的数据类型来避免,该类型std::array是为许多其他STL类设计的.

作为旁注,除非有充分的理由使用固定大小的数组,std::vector否则作为连续的内存数据结构可能是更好的选择.


Bri*_*ian 6

std::array 和C风格的数组类似:

  • 它们都存储连续的对象序列
  • 它们都是聚合类型,因此可以使用聚合初始化进行初始化
  • 它们的大小在编译时是已知的
  • 它们不使用动态内存分配

一个重要的优点std::array是它可以通过值传递,并且不会像C样式数组那样隐式地衰减到指针.


Mr.*_*C64 5

在这两种情况下,都会在堆栈上创建数组.

但是,STL的std::array类模板比第二种情况的"原始"C类数组语法提供了一些优势:

int array1[arraySize];
Run Code Online (Sandbox Code Playgroud)

例如,对于std::array你有一个典型的STL接口,具有类似的方法size(其可以使用用于查询该数组元素数), ,front,back,at等.

你可以在这里找到更多细节.

  • "*在这两种情况下,数组都是在堆栈上创建的" - 除非它是在堆上分配的结构/类的成员. (3认同)