使用 std::array vs 数组传递对象数组
Passing object array with 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;
}
.
Struct Apple {
std::string color;
}
void colors(std::array<Apple, 10>& A) {
A[0].color = "red";
}
int main() {
std::array<Apple, 10> apples;
colors(apples);
return 0;
}
这两个函数使用GCC 7.3
在x86_64
上生成相同的代码。
这里: https://godbolt.org/g/aguVfF
第一个例子:
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
当传递内置数组时,它们会衰减到指向其第一个元素的指针。此外,当对象通过通常使用指针实现的引用传递时。
由于std::array
是围绕内置数组的非常薄的包装器,因此其地址可能与其第一个元素的地址相同。编译器的优化器可以直接看穿它。
您不太可能找到任何使用std::array
比内置数组慢的示例,因为std::array
基本上是一个包裹在零成本语法糖中的内置数组,它利用了内置版本没有的编译时信息(如数组的大小)。
你在 C 和 C++ 中都陷入了一个常见的初学者错误——你不能将数组作为参数传递给函数。 语言不允许。 如果将数组声明为参数的函数,编译器(静默地)会将其更改为指针,因为数组可以隐式转换为指针(通常在大多数地方都是这样)。
所以你的第一个例子是:
void colors(Apple *A) {
A[0].color = "red";
}
所以现在很明显,你的问题实际上是:传递指针和传递引用之间的性能有什么区别吗?
否 - 引用和指针以与地址相同的方式实现,因此它们之间的性能没有差异。
性能方面,没有。它们都只是在内存地址周围洗牌,因此性能是相同的。
在风格方面,我总是建议std::array
而不是C数组。C 数组仅在C++中用于向后兼容旧代码。新东西具有遵循标准容器类接口的优点,因此可以与<algorithm>
和其他库中所有花哨的 STL 泛型方法一起使用。它也知道自己的规模,这本身就是一个相当大的胜利。
性能方面,这取决于数组的大小、编译器和使用的编译选项。基准。
当你传递一个常规数组时,它基本上衰减为一个指针,所以你只有传递一个指针的开销。如果传递std::array
副本,则需要复制整个数组。如果通过引用传递它,则会产生传递引用的开销(这通常与传递指针相同)。
我仍然强烈建议您使用std::array
以确保类型安全。
- 销毁C++中动态分配的内存(数组对象)
- 数组对象的生存期是否在重用其元素存储时结束?
- 为什么顶点数组对象会导致错误?
- 具有纯虚函数和指针数组对象类型的父类的指针数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- OpenGL 顶点数组对象与 tinyobjloader
- 将数组/对象/结构列表从C#库中传递给C MFC应用程序
- C++ RapidJson 帮助反序列化数组对象
- ptrdiff_t可以表示指向同一数组对象元素的指针的所有减法吗?
- 检查成员函数是否返回临时对象或数组对象
- 为什么 std::variant 不能容纳数组对象类型,而联合可以?
- 当数组对象以函数参数传递时,为什么复制构造函数会自称
- 如何使用箭头指针打印出一类数组对象,这些对象中有多个分数
- C++17 std::shared_ptr<> 类数组对象的重载运算符 []
- 添加两个具有运算符重载的数组对象,从而导致分段错误
- opengl:两个不同的矢量可以绑定到同一个顶点数组对象吗
- 使用相同的数据填充数组对象或使用指针
- 方法用于最快的分配,并且不需要将动态大小的数组对象作为局部变量
- 如何将2d数组对象传递给c++中的函数
- ReferenceTable溢出(jni-android),数组对象释放