我想与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
是安全的(即,它们是否像向量一样具有智能指针管理?)
答案 0 :(得分:5)
使其与其他容器兼容。
通过这种方式,您可以拥有一个模板函数,该函数可以收集任何集合,并确保无论是std::vector
还是std::array
,它都能正常工作。
答案 1 :(得分:2)
capacity
中的{p> vector
是vector
的最大容量..它可能与size
相同或不同。size
。
vector
是{{1}}中当前的元素数。
出于性能原因,如果您事先知道向量的最大大小(或有猜测),则可以预先确定向量的容量(而不是使用其默认值)。这可能会显着提高代码的性能,因为您不必在每次迭代时重新分配(添加元素时)。
答案 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::array
和std::vector
都没有“智能指针管理”,至少在我考虑它们的方式。它们都提供迭代器类型,以及begin/end/rbegin/rend
等函数,可以遍历容器中的元素。当人们说“智能指针”时,我会想到shared_ptr/unique_ptr/auto_ptr/etc
。
通常,std::array
存储在堆栈中,而std::vector
在堆上分配存储。在性能关键型应用程序中,这是std::array
的一大优势。在堆上分配内存可能比使用堆栈慢100或1000倍,尤其是在多线程应用程序中。