3

我想弄乱一下,std::array看看它与std::vector. 到目前为止,我只发现了一个主要区别。

Sentence sentence = { "Hello", "from", "GCC", __VERSION__, "!" };  
std::array<std::string, 10> a;
std::copy(sentence.begin(), sentence.end(), a.begin());

int i = 0;
for (const auto& e : a)
{
    i++;
    std::cout << e << std::endl;
}
std::cout << i << std::endl;

// outputs 10

i = 0;
for (const auto& e : sentence)
{
    i++;
    std::cout << e << std::endl;
}
std::cout << i << std::endl;

// outputs 5

for (int i = 0; i < a.size(); i++)
    std::cout << i << " " << a[i] << std::endl;

// outputs 0 Hello
// ...
//         4 !
//         5-9 is blank

for (int i = 0; i < sentence.size(); i++)
    std::cout << i << " " << sentence[i] << std::endl;

// outputs 0 Hello
// ...
//         4 !
// stops here


// The following outputs the same as above
i = 0;

for (auto it = a.begin(); it != a.end(); it++)
{
    std::cout << i << " " << *it << std::endl;
    i++;
}
std::cout << i << std::endl;
i = 0;
for (auto it = sentence.begin(); it != sentence.end(); it++)
{
    std::cout << i << " " << *it << std::endl;   
    i++;
}
std::cout << i << std::endl;

所以从我所见,std::array's sizeandmax_size是多余的,但是std::vector's sizeandcapacity可以不同或相同。这甚至从这句话中得到证实:

数组对象的 size 和 max_size 始终匹配。

那么为什么std::array会有冗余尺寸功能呢?更重要的是,您是否会认为它std::array的大小不一定与std::vector的大小相同,因为向量具有容量?此外,这是否意味着std::arrays 是安全的(即,它们是否像向量一样具有智能指针管理?)

4

5 回答 5

6

使其与其他容器兼容。

通过这种方式,您可以拥有一个模板函数,该函数接受任何集合,并确保无论它是 astd::vector还是std::array.

于 2013-05-05T02:21:52.253 回答
3

capacityin vector是 .. 的最大容量,vector它可能与它的 .. 相同也可能不同sizesize是 中的当前元素数vector

出于性能原因,如果您事先知道向量的最大大小(或有猜测),则可以预先确定向量的容量(而不是使用其默认值)。这可能会显着提高代码的性能,因为您不必在每次迭代时重新分配(当您添加元素时)。

http://www.cplusplus.com/reference/vector/vector/capacity/

于 2013-05-05T02:25:29.013 回答
2

更重要的区别是std::vector有一个resize功能,而std::array没有。

实例的大小std::array(如普通数组的大小)在实例化时是固定的(实际上它的大小必须在编译时知道,并且是一个常量表达式)。但是,在std::vector运行时实例化后,可以调整实例的大小。

此外std::arrays,不同尺寸的为不同的类型,而std::vectors不同尺寸的为同一类型。

使用 a std::arrayover a的唯一原因std::vector是 astd::array使用的空间更少,速度更快。Astd::vector需要存储其大小和指向堆分配后备存储的指针,该后备存储可能具有额外的填充以允许调整大小。Astd::array是就地分配的(没有间接指针),并且它的size函数也是静态已知的,因此调用std::array.size()将编译为一个常量(它constexpr实际上是一个函数)。

于 2013-05-05T03:30:28.677 回答
1

稍微扩展一下,在这个主题上,anstd::array非常接近于数组的实际设计,例如数组char[]的最大大小是数组的大小。这是因为数组可以被认为具有不可变的大小。除了完全重新分配内存之外,这是一个无法更改的大小。与 astd::vector可以设置为具有 acapacity和大小可以从 0 到 that 的任意值不同capacity,但是一旦它传递了该capacity值,每个新元素将导致完全重新创建和分配vector.

于 2013-05-05T02:28:19.663 回答
1

正如您所指出的, astd::array始终是相同的大小。size() == capacity(). 这意味着当您创建 时,您会收到对的默认构造函数的std::array<T, 5>五次调用。另一方面,TA不会默认构造任何元素。std::vector<T>调用reserve(5)向量仍然不会导致构建任何项目。

std::array没有std::vector“智能指针管理”,至少在我看来是这样。它们都提供了迭代器类型和类似的函数begin/end/rbegin/rend,让您可以遍历容器中的元素。当人们说“智能指针”时,我会想到shared_ptr/unique_ptr/auto_ptr/etc.

通常,astd::array存储在堆栈上,而 astd::vector分配存储在堆上。在性能关键型应用程序中,这是std::array. 在堆上分配内存可能比使用堆栈慢 100 倍或 1000 倍,尤其是在多线程应用程序中。

于 2013-05-07T18:02:38.937 回答