使用遗留代码,我问自己应该用新的std :: array替换固定大小的C样式数组吗? E. g。
static const int TABLE_SIZE = 64;
double table[TABLE_SIZE];
替换为
std::array<double, TABLE_SIZE> table;
虽然我看到将std :: vector用于可变大小数组的好处,但我没有看到它们具有固定大小。 table.size()
无论如何都是已知的,std::begin(), std::end()
因为自由函数也可用于具有C风格数组的STL算法。因此,除了更符合标准外,我还能错过更多的好处吗?替换所有事件是否值得工作还是被认为是最佳实践?
答案 0 :(得分:10)
AFAIK std::array
只提供更好的类似STL的接口来处理而不是正常的C阵列。在性能和功能方面,两个选项可以大致相同,但std::array
可以用作标准容器。
另一个特性:它们可能被视为tuples,因为它们提供类似元组的访问功能。
最后但并非最不重要的是user2079303注意到:如果您的代码将由新手程序员使用,它可以在将其作为参数传递时阻止数组衰减过程。
如果您想知道是否应该用std :: arrays替换所有C风格的数组,那么如果您要开发一些新的功能和/或重写,答案是肯定的。您的一些代码可以利用这些功能。如果您只是简单地用带有std :: arrays的C数组替换它(不接触任何其他内容),那么它可能是不值得的。
答案 1 :(得分:6)
还有一件事我还没有提到:std::array::at()
。堆栈损坏可能非常讨厌调试,并且由于堆栈损坏导致的错误可能会隐藏很长一段时间。 :(与Address Sanitizer相比,这种情况已经变得有点了。但是,我更喜欢检查地址消毒剂。
在我看来,绑定检查元素访问本身就足以使用std::array
而不是C样式数组。
答案 2 :(得分:5)
std::array
的另一个功能是可以复制分配;
std::array<int, 3> a = {1, 2, 3};
std::array<int, 3> b = {4, 5, 6};
std::array<int, 3> c = a; // copy-construction
a = b; // copy-assignment
答案 3 :(得分:4)
答案 4 :(得分:4)
这取决于用例。性能和空间方面,它们应该是相同的,除了std::array
携带的大小成员。编辑:甚至大小将被优化。所以即使在空间方面它也是相同的。实现通常可以:
template <class T, std::size_t N>
class array {
...
public:
contsexpr std::size_t size() const { return N; }
}
远离存储字符串的大小。
传递它时, std::array<T, N>
不会衰减到指针。但是在你的用例中你有一个全局变量,我想。我不会改变它已经起作用的只是让它看起来更好。
另一方面,如果您想将任意大小的std::array
传递给某个函数,则必须对其进行模板化处理:
template <std::size_t N>
void f(std::array<MyT, N> const & arr);
std::array
的优点
std::array
std::array
的一般功能,
你必须在标题中作为模板。在C数组中,您可以这样做:
void f(MyT const * arr, std::size_t size);
它可以用于任何数组,无论长度如何。 这样安全性较低,但在.cpp中隐藏依赖项更方便 文件,因为以后你可以在.cpp文件中编写函数。
但正如我所说,考虑到您的用例,请选择。我不会 更改正在工作且不会被曝光的代码(例如, 如果它是一个永远不被视为函数参数的全局变量) 以任何不安全的方式。
答案 5 :(得分:2)
我认为std :: array比c风格的数组有许多优点。因此,有必要尝试替换所有出现或至少开始使用std :: array而不是c-style。有关更多信息,我们可以看一下Bjarne Stroustrup的C ++ 11 FAQ提到的here。
换句话说,它非常像一个没有问题的内置数组。
关于你对table.size()的观点是已知的,但只有在有人在定义它的上下文中使用数组时它才有效。如果我们需要将它传递给其他函数,那么它就不知道了,我们必须通过它。
答案 6 :(得分:1)
有许多事情:
get
,tuple_size
,tuple_element
)与编译时间检查边界访问第一点非常明显,主要是通用代码的优点。第二点有点模糊:从语义arrayS
开始只是退化tupleS
(当然tupleS
不保证在内存中顺序存储)。这样处理它们是有道理的,并且处理元组的代码也可以在很大程度上与数组一起工作。第三点是一个很好的奖励,并为代码增加了一些安全性。