【问题标题】:Manipulating std::array in a function在函数中操作 std::array
【发布时间】:2018-08-31 04:44:55
【问题描述】:

我的代码中有一个固定大小的多维数组,我需要能够在单独的函数中更改其中的值。我想知道,std::arrays 是在方法中作为引用传递还是复制?那么我可以这样做吗:

using std::array;

void foo (array<array<int,WIDTH>,HEIGHT> bar);
//manipulates the values in the array
...

int main() {
  array<array<int,WIDTH>,HEIGHT> baz;
  ...
  foo(baz);
  //baz is changed
}

或者我是否需要明确地将其转换为参考?我担心如果我创建了一个返回副本的数组函数,它会太乱而且没有那么快。

【问题讨论】:

  • std::array是一个以常规方式运行的常规类。没有类型作为参数得到特殊处理。
  • 我假设因为它是 c 数组的包装器,所以它也将作为引用传递。
  • 如果您有一个包含 C 数组的普通类定义,然后按值传递该类的实例,则内部数组成员字段将 复制 到一个新的实例。 std::array 的行为没有什么不同。
  • 我猜您正在考虑将 C 数组衰减为指向其第一个元素的指针作为参数。请注意,在这种情况下,参数与数组的类型不同。实际参数是一个指针,它像其他所有内容一样被复制。
  • @Comrade_Comski 我想std::array 的设计目标之一是摆脱常规数组所获得的特殊处理。不然有什么意义?

标签: c++ stdarray


【解决方案1】:

我想知道,std::arrays 是在方法中作为引用传递还是复制?

std::array 是一个值类型。如果您按值传递,则会(从概念上)制作一个副本。

这与 c 样式数组 (int bar[HEIGHT][WIDTH]) 的行为不同。 c 风格的数组是通过引用传递的。这是由于很久以前 C 语言中的一个基本设计决定(有人会说是错误)。

我需要明确地将其转换为参考吗?

如果您希望传递参考,可以。

我担心如果我创建一个返回副本的数组函数会太乱

函数式程序员会争辩说它更干净。

而且没有那么快。

小心这样的假设。除其他原因外,

a) 编译器并不总是按照你告诉他们的去做。他们可以编写代码,其效果与您告诉他们的一样,但更快地实现相同的结果。 (谷歌:“as-if rule c++”)

b) 现代 CPU 架构经过专门设计,非常擅长移动连续的内存块。

尽可能编写最简洁的代码,使用抽象概念清楚地表达您的意图。如果程序运行太慢、使用太多内存、使用太多功率或您的最终用户抱怨,那么也许是时候关注按引用或按值优化了。

但是,我可以向您保证,您在执行速度方面看到的任何延迟都更有可能是在您处理 IO 的过程中,或者是由于选择了具有高时间复杂度的算法。

【讨论】:

  • 谢谢。是否应该选择返还副本,该功能是否保证在完成后删除多余的副本?
  • @Daniel 是的。通常甚至不会制作额外的副本。编译器非常聪明。
  • 也很常见:通过 const 引用传递参数,返回一个新创建的结果 (Matrix add(Matrix const&amp; x, Matrix const&amp; y);)
  • @RichardHodges 我对“通过引用传递 C 样式的数组”有点麻烦 - 至于我的理解,如果是这样,1. 不应该改变类型(数组衰减到指针),2.sizeof 应该产生数组的大小,而不是指针的大小。更糟糕的是:可以真的通过引用传递数组:void f(int (&amp;x)[7])(除了那个细节,很好的答案......)
  • @Aconcagua 1. 是的,这正是现实中发生的事情。 2. 欢迎来到将 c 样式数组传递给函数的混乱。是的,您的f 示例与您编写void f(int x[7]) 的含义完全相同
【解决方案2】:

如果您想避免复制,请通过引用(或指针)传递:

void foo (array<array<int,WIDTH>,HEIGHT> &bar);

【讨论】:

    猜你喜欢
    • 2016-05-31
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 2012-12-08
    • 2015-05-27
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多