std :: array vs std :: vector细微差别

时间:2013-05-05 02:12:21

标签: arrays c++11 vector

我想与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的{​​{1}}和size是多余的,但是max_size的{​​{1}}和std::vector可以是不同的或相同的。这甚至可以从这句话得到证实:

  

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

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

5 个答案:

答案 0 :(得分:5)

使其与其他容器兼容。

通过这种方式,您可以拥有一个模板函数,该函数可以收集任何集合,并确保无论是std::vector还是std::array,它都能正常工作。

答案 1 :(得分:2)

capacity中的{p> vectorvector的最大容量..它可能与size相同或不同。sizevector是{{1}}中当前的元素数。

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

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

答案 2 :(得分:2)

更重要的区别是std::vector具有resize功能,而std::array则没有。{/ p>

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

不同大小的std::arrays进一步是不同的类型,而不同大小的std::vectors是相同的类型。

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

答案 3 :(得分:1)

为了扩展一点,关于这个主题,std::array非常接近数组的实际设计,例如char[],其中数组的最大大小是数组的大小。这是因为可以认为该数组具有不可变的大小。除了完全重新分配内存之外,这是一个无法更改的大小。与std::vector不同,capacity可以设置为capacity且大小可以是从0到capacity的任何位置,但是一旦它通过vector值,每个新元素将导致{{1}}内的基础数组的完全重新创建和分配。

答案 4 :(得分:1)

如您所述,std::array的大小始终相同。 size() == capacity()。这意味着当您创建std::array<T, 5>时,您将获得对T的默认构造函数的五次调用。另一方面,std::vector<T>不会默认构造任何元素。在向量上调用reserve(5)仍然不会导致任何项目被构造。

std::arraystd::vector都没有“智能指针管理”,至少在我考虑它们的方式。它们都提供迭代器类型,以及begin/end/rbegin/rend等函数,可以遍历容器中的元素。当人们说“智能指针”时,我会想到shared_ptr/unique_ptr/auto_ptr/etc

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