std::array
远远优于C阵列。即使我想与遗留代码进行互操作,也可以使用std::array::data()
。我有什么理由想要老式的阵列吗?
std::array
远远优于C阵列。即使我想与遗留代码进行互操作,也可以使用std::array::data()
。我有什么理由想要老式的阵列吗?
Answers:
除非我没有错过任何内容(我没有太严格地遵循标准的最新更改),否则仍然保留C样式数组的大多数用法。 std::array
确实允许静态初始化,但仍然不会为您计算初始化次数。而且由于之前C样式数组的唯一真正用途std::array
是用于静态初始化的表,因此:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
使用常规begin
和end
模板函数(在C ++ 11中采用)对它们进行迭代。不用说大小,编译器根据初始化程序的数量确定大小。
编辑:我忘记的另一件事:字符串文字仍然是C样式数组;即与类型char[]
。我认为没有人会因为我们有而排除使用字符串文字std::array
。
const char[]
不,要坦率地说。并以30个字符为单位。
当然,您需要C数组来实现 std::array
,但这并不是用户想要C数组的真正原因。另外,不,std::array
性能不比C数组低,并且可以选择进行边界检查访问。最后,对于任何C ++程序而言,完全依赖标准库是完全合理的(从某种意义上说,它就是标准库),如果您无法访问标准库,则编译器将不符合标准,并且问题被标记为“ C ++”,而不是“ C ++和那些因为感觉不合适而漏掉了一半规格的非C ++东西”。
std::array
在独立的C ++ 11实现中实现的编译器,我将有严重的怀疑。
似乎使用C数组比使用多维数组要容易std::array
。例如,
char c_arr[5][6][7];
相对于
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
同样由于C数组的自动衰减特性,c_arr[i]
在上面的示例中将衰减到指针,您只需要将其余维度作为另外两个参数传递即可。我的观点是c_arr
,复制并不昂贵。但是,cpp_arr[i]
复制将非常昂贵。
array
在不损失尺寸的情况下将多维传递给函数。并且,如果将其传递给函数模板,则该函数既可以推导维数又可以推导每个维数的大小,或者只是两个维数之一。这对于主要在任意维度上工作的科学模板库可能会很有趣。
template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;
应该解决所有这些问题。
c_arr
是非常复制贵!您必须自己提供代码。它将衰变的指针与副本相比,更接近于std::array
引用,如果需要,可以使用传递引用。
std::size_t
不是int
吗?抱歉挑剔,但这将使它变得通用。
size_t
如果您愿意的话,您可以做到,尽管我无法想象在许多情况下需要具有超过40亿行或列的数组。
正如Sumant所说,内置C数组比使用多维数组要容易得多 std::array
。
嵌套时 std::array
将变得非常难以阅读和不必要的冗长。
例如:
std::array<std::array<int, 3>, 3> arr1;
相比
char c_arr[3][3];
此外,需要注意的是begin()
,end()
和size()
所有返回无意义的值,当你窝std::array
。
由于这些原因,我创建了自己的固定大小的多维数组容器array_2d
和array_3d
。它们类似于std::array
但适用于2维和3维的多维数组。与内置多维数组相比,它们更安全并且性能也不差。我没有为尺寸大于3的多维数组提供容器,因为它们并不常见。在C ++ 0x中,可以创建可变参数模板版本,该版本支持任意数量的尺寸。
二维变量的示例:
//Create an array 3 x 5 (Notice the extra pair of braces)
fsma::array_2d <double, 3, 5> my2darr = {{
{ 32.19, 47.29, 31.99, 19.11, 11.19},
{ 11.29, 22.49, 33.47, 17.29, 5.01 },
{ 41.97, 22.09, 9.76, 22.55, 6.22 }
}};
完整的文档可以在这里找到:
http://fsma.googlecode.com/files/fsma.html
您可以在此处下载该库:
arr[x][y]
,您无法确定arr
是数组数组,指针数组,指向数组的指针还是指向指针的指针。所有实现方式都是合法的,具体取决于您的需求。可能在大多数实际的多维数组用例中,需要在运行时确定大小。
实际上,C ++中可用的C样式数组的功能远不如真正的C数组。区别在于,在C中,数组类型可以具有运行时大小。以下是有效的C代码,但不能用C ++ C样式数组或C ++ array<>
类型表示:
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
在C ++中,您将不得不在堆上分配临时数组:
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
这是无法实现的std::array<>
,因为bar
在编译时未知,因此需要使用C ++中的C样式数组或std::vector<>
。
尽管第一个示例可以相对轻松地用C ++表示(尽管需要new[]
和delete[]
),但是如果没有以下条件,则不能在C ++中实现以下功能std::vector<>
:
void smoothImage(int width, int height, int (*pixels)[width]) {
int (*copy)[width] = malloc(height*sizeof(*copy));
memcpy(copy, pixels, height*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y][x] = //compute smoothed value based on data around copy[y][x]
}
}
free(copy);
}
关键是,指向行数组的指针int (*)[width]
不能使用C ++中的运行时宽度,这使得C ++中的任何图像处理代码都比C语言中的复杂得多。图像处理示例的典型C ++实现如下所示:
void smoothImage(int width, int height, int* pixels) {
int* copy = new int[height*width];
memcpy(copy, pixels, height*width*sizeof(*copy));
for(y = height; y--; ) {
for(x = width; x--; ) {
pixels[y*width + x] = //compute smoothed value based on data around copy[y*width + x]
}
}
delete[] copy;
}
此代码执行与上面的C代码完全相同的计算,但是无论使用了哪里的索引,都需要手动执行索引计算。对于2D情况,这仍然是可行的(即使有很多机会使索引计算错误)。但是,在3D情况下,它确实很讨厌。
我喜欢用C ++编写代码。但是,每当需要处理多维数据时,我都会真正问自己是否应该将代码的这一部分移至C。
gcc
例如)。C11使很多有趣的东西成为可选项,我不认为那是因为他们想取缔该功能。我倾向于认为这表明他们想降低编写完全符合标准的编译器的水平:VLA很难实现,而且很多代码也可以不这样做,因此对于某些新的编译器来说,这是有意义的平台,不必立即实施VLA。
可能std::array
不是很慢。但是我使用简单的存储做了一些基准测试,并从std :: array;中读取了内容;请参阅以下基准测试结果(在W8.1,VS2013更新4上):
ARR_SIZE: 100 * 1000
Avrg = Tick / ARR_SIZE;
test_arr_without_init
==>VMem: 5.15Mb
==>PMem: 8.94Mb
==>Tick: 3132
==>Avrg: 0.03132
test_arr_with_init_array_at
==>VMem: 5.16Mb
==>PMem: 8.98Mb
==>Tick: 925
==>Avrg: 0.00925
test_arr_with_array_at
==>VMem: 5.16Mb
==>PMem: 8.97Mb
==>Tick: 769
==>Avrg: 0.00769
test_c_arr_without_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 358
==>Avrg: 0.00358
test_c_arr_with_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 305
==>Avrg: 0.00305
根据负号,我使用的代码在pastebin中(link)
基准类代码在这里 ;
我对基准测试一无所知...我的代码可能有缺陷
long test_arr_without_init() { return ARR_SIZE; }
void test_arr_without_init() {}
现在。您确实需要跳过所有步骤,以确保要测量的代码就是要测量的代码。
std::array
std::array
性能将不如C数组。
at()
,不在。没有性能下降或代码膨胀,编译器旨在优化这种情况。而且,当然,添加检查功能是一种出色的调试工具,并且具有很大的优势。@Lou Franco:所有C ++代码都可能依赖于标准库-这就是它的用途。@Earlz:如果没有可用的STL,则它不是C ++,到此为止。operator[]
std::vector
std::array
std::array
大于等效的C数组。