使用std::array vs array传递对象数组 今天我和我的朋友讨论了如何在C++中传递对象数组的正确方法。这两者之间是否存在任何效率差异: Struct Apple { std::string color; } void colors(Apple A[]) { A[0].color = "red"; } int main() { Appple apples[10]; colors(apples); return 0; }

使用std::array vs array传递对象数组 今天我和我的朋友讨论了如何在C++中传递对象数组的正确方法。这两者之间是否存在任何效率差异: Struct Apple { std::string color; } void colors(Apple A[]) { A[0].color = "red"; } int main() { Appple apples[10]; colors(apples); return 0; },c++,arrays,object,struct,stdarray,C++,Arrays,Object,Struct,Stdarray,Struct苹果{ 字符串颜色; } 空颜色(标准::数组和A){ A[0].color=“红色”; } int main(){ 阵列苹果; 颜色(苹果); 返回0; } 性能方面,它取决于数组的大小、编译器和使用的编译选项。基准 当你传递一个正则数组时,它基本上会衰减为一个指针,所以你只需要传递一个指针的开销。如果通过复制传递std::array,则需要复制整个数组。如果通过引用传递,则传递引用的开销(通常与传递指针相同) 我仍然强烈建议您使用std::array,以确保类型安全。性能方面,没

Struct苹果{
字符串颜色;
}
空颜色(标准::数组和A){
A[0].color=“红色”;
}
int main(){
阵列苹果;
颜色(苹果);
返回0;
}

性能方面,它取决于数组的大小、编译器和使用的编译选项。基准

当你传递一个正则数组时,它基本上会衰减为一个指针,所以你只需要传递一个指针的开销。如果通过复制传递
std::array
,则需要复制整个数组。如果通过引用传递,则传递引用的开销(通常与传递指针相同)


我仍然强烈建议您使用
std::array
,以确保类型安全。

性能方面,没有。它们都只是在内存地址上来回移动,因此性能是相同的


就风格而言,我总是推荐
std::array
而不是C数组。C数组仅在C++中与旧代码反向兼容。这种新东西具有遵循标准容器类接口的优点,因此可以与
和其他库中所有花哨的STL通用方法一起使用。它也知道自己的规模,这本身就是一个相当大的胜利

> P>你在C和C++中都会陷入一个常见的初学者错误,你不能把数组作为参数传递给函数。语言不允许这样做。如果您声明一个以数组作为参数的函数,编译器(以静默方式)会将其更改为poiner,因为数组可以隐式转换为指针(在大多数情况下通常是这样)

所以你的第一个例子是:

void colors(Apple *A) {
    A[0].color = "red";
}
现在很明显,您的问题是:传递指针和传递引用之间的性能有什么区别吗


否--引用和指针以相同的方式实现--作为地址--因此它们之间的性能没有差异。

这两个函数使用
x86\u 64
上的
GCC 7.3
生成相同的代码

在这里:

第一个例子:

void colors(Apple A[]) {
    A[0].color = 12;
}

_Z6colorsP5Apple: 
  mov DWORD PTR [rdi], 12
  ret
第二个例子:

void colors(std::array<Apple, 10>& A) {
    A[0].color = 13;
}

_Z6colorsRSt5arrayI5AppleLm10EE:
  mov DWORD PTR [rdi], 13
  ret
void颜色(标准::数组&A){
A[0]。颜色=13;
}
_Z6ColorsRT5ArrayI5Applelm10EE:
mov DWORD PTR[rdi],13
ret
当传递内置数组时,它们衰减为指向第一个元素的指针。当对象通过引用传递时,通常使用指针实现

由于
std::array
是内置数组的一个非常薄的包装器,因此它的地址可能与其第一个元素的地址相同。编译器的优化器可以看穿它


您不太可能找到任何使用
std::array
比内置数组慢的例子,因为
std::array
基本上是一个内置数组,用零成本语法糖包装,利用内置版本没有的编译时信息(如数组大小).

性能方面?是的。抱歉,如果我不清楚:)。@Marker它发生在编译时“代码A比代码B快吗?”-为什么不试试看。@Marker
std::array
是一个聚合,所以它没有构造函数。如果你把一些可以简单初始化的东西放在里面,那么只会有一个堆栈分配,其他什么都没有。这是一个零成本的抽象。可能不是更安全的类型,但它知道自己的大小。如果您通过引用传递,编译器可以更确定变量在内存中的位置,这样就可以在大型程序中进行更多优化,这是一个额外的好处。当您在编译器优化中处理指针时,存在着难以置信的不确定性。@jotik这是所有不错的功能,但类型安全性是不同的……请注意,对于
std::array
示例,函数的参数是引用,因此它不是复制。通过引用传递的本机数组也具有它的大小<代码>无效颜色(苹果(&)[10])So
void(int A[])
void(int*A)
不一样?@dqmis:它们都不是函数——它们都是类型。我反对投票,因为说数组作为指向其第一个参数的指针传递并不能真正证明std::array更快或更慢,或者原始数组与std::array有其他区别(安全性、语义、规模、防泄漏性、可读性……)@jotik:“撤销”其他人的投票权不是你的工作。我投了更高的票,因为即使它没有直接回答OP问题(实际上我认为是的),它也有助于更好地理解问题。
void colors(std::array<Apple, 10>& A) {
    A[0].color = 13;
}

_Z6colorsRSt5arrayI5AppleLm10EE:
  mov DWORD PTR [rdi], 13
  ret