在c ++ 11中复制常量数组的最简洁方法

bob*_*uba 40 c++ arrays optimization copy c++11

我经常发现自己想要复制具有恒定大小的数组的内容,我通常只是写下以下内容:

float a[4] = {0,1,2,3};
float b[4];

for(int i=0; i<4; i++){
    b[i]=a[i];
}
Run Code Online (Sandbox Code Playgroud)

最近,我正在编写一个用于教育目的的线性微积分库,我想知道是否有更好的方法来实现它.

我想到的第一件事就是使用memcpy:

memcpy(b, a, sizeof(float) * 4);
Run Code Online (Sandbox Code Playgroud)

但这看起来很像c-like而且容易出错.我喜欢在编译时遇到错误,对于具有非平凡复制构造函数的数据类型,或者如果我忘记与sizeof(datatype)相乘,这会变得很难看.

由于我正在编写一个我将要密集使用的数学库,因此性能对我来说非常重要.今天的编译器是否足够聪明,可以理解第一个例子只是复制一块内存并将其优化为与第二个解决方案一样高效?

也许标准库中有一个功能可以帮助我?c ++ 11中的新东西?或者我应该只创建一个宏或模板函数?

Ben*_*ley 62

如果你使用std::array而不是内置数组(你应该使用),它变得非常简单.复制数组与复制任何其他对象相同.

std::array<float,4> a = {0,1,2,3};
std::array<float,4> b = a;
Run Code Online (Sandbox Code Playgroud)

  • @BenjaminLindley你没有明白我的观点.`std :: copy()`函数模板接受大小为*运行时常量*.如果在编译时已知该数字,则编译器*可以*进行一些优化.使用`std :: array <> :: operator =`这在编译时拼写出来:没有优化(或不)运行时大小的代码.我不喜欢依靠编译器来进行这些类型的优化. (4认同)
  • @ user650261:问题不在于 C 风格的数组。它是关于恒定大小的数组。拥有恒定大小数组的一种方法是使用 c 样式数组。OP 在提出问题之前显然不知道的另一种方法是 `std::array`。事实证明,`std::array` 几乎在所有方面都更胜一筹。特别是,它在解决 OP 真正关心的问题方面要好得多。 (4认同)
  • 我有点困惑。这个问题是关于 C 风格的数组。为什么使用 std::arrays 的解决方案?对我来说,这绝对不是这个问题的规范答案。 (2认同)

Mys*_*ial 43

C++ 03的方法是使用std::copy():

float a[4] = {0,1,2,3};
float b[4];

std::copy(a,a + 4, b);
Run Code Online (Sandbox Code Playgroud)

那就像它变得干净一样.在C++ 11上更喜欢

std::copy(std::begin(a), std::end(a), std::begin(b));
Run Code Online (Sandbox Code Playgroud)

或者更好的是,使用std :: array并免费获得赋值:

std::array<float,4> a = {0,1,2,3};
auto b = a;
Run Code Online (Sandbox Code Playgroud)

  • @j_random_hacker:在C++ 11中,`std:copy(std :: begin(a),std :: end(a),std :: begin(b))`. (19认同)
  • 为了避免在你改变数组大小的情况下悄然破坏,我建议`std :: copy(a,a + sizeof(a)/ sizeof(a [0]),b);`.更好的是,将`sizeof()`垃圾包裹在一个宏 - 甚至更好的用户中,改为使用函数模板:`template <typename T,size_t N> size_t size((T&)[N]){return N; }` (5认同)
  • 反对者关心评论吗?如果我不知道出了什么问题,就很难改进某些东西。 (3认同)

Pio*_*ycz 16

对C++ 03(以及C)解决方案感兴趣 - 总是使用包含数组而不是单独数组的struct:

struct s { float arr[5]; };
Run Code Online (Sandbox Code Playgroud)

结构默认是可复制的.

已经提到过它在C++ 11中的等价物, std::array<float,5>;

  • 关于c ++ 03结构包装的好点.我需要更好地记住这个:) (2认同)

Shi*_*hah 7

下面的方法也适用于普通数组以及 std:array。

float a[4] = {0,1,2,3};
float b[4];

std::copy(std::begin(a), std::end(a), b);
Run Code Online (Sandbox Code Playgroud)

  • 请注意为什么要投反对票。这是可行的,它确实是 C++ 中的首选方式,也适用于常见的数组,我一直使用它。 (2认同)
  • @CodingLab,不同意。我的代码中充斥着这种情况,如果您使用现实世界中丰富的 C 风格数组,那么这是一个很好的解决方案。 (2认同)