什么是安全的方式来填充多维数组使用std :: fill? [英] what's the safe way to fill multidimensional array using std::fill?

查看:167
本文介绍了什么是安全的方式来填充多维数组使用std :: fill?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是我使用的:

class something
{
    char flags[26][80];
} a;

std::fill(&a.flags[0][0], &a.flags[0][0]+26*80, 0);

(更新:我应该清楚,我在类中使用这个。

(Update: I should have made it clear earlier that I'm using this inside a class.)

推荐答案

初始化 0 定义:

char flags[26][80] = {};

如果要使用 std :: fill ,或者您想要重置数组,我觉得这更好一些:

If you want to use std::fill, or you want to reset the array, I find this a little better:

char flags[26][80];
std::fill( &flags[0][0], &flags[0][0] + sizeof(flags) /* / sizeof(flags[0][0]) */, 0 );

填充尺寸将允许您更改尺寸并保持填充不变。 sizeof(flags [0] [0]) 1 (char)== 1 ),但您可能希望将其保留,以防您随时更改类型。

The fill expressed in terms of the array size will allow you to change the dimensions and keep the fill untouched. The sizeof(flags[0][0]) is 1 in your case (sizeof(char)==1), but you might want to leave it there in case you want to change the type at any point.

在这个特殊的情况下( flags --integral类型的数组)我甚至可以考虑使用 memset / em>选项(如果数组类型更改为非pod类型,这将会中断):

In this particular case (array of flags --integral type) I could even consider using memset even if it is the least safe alternative (this will break if the array type is changed to a non-pod type):

memset( &flags[0][0], 0, sizeof(flags) );

请注意,在这三种情况下,数组大小只能键入一次,编译器会推断其余。这是有点安全,因为它给程序员错误留下较少的空间(改变一个地方的大小,在其他地方忘记它)。

Note that in all three cases, the array sizes are typed only once, and the compiler deduces the rest. That is a little safer as it leaves less room for programmer errors (change the size in one place, forget it in the others).

编辑:你已经更新了代码,因为它是不会编译,因为数组是私有的,你试图从外部初始化。根据你的类是否实际上是一个聚合(并希望保持它的样子),或者你是否要添加一个构造函数到类中,你可以使用不同的方法。

You have updated the code, and as it is it won't compile as the array is private and you are trying to initialize it externally. Depending on whether your class is actually an aggregate (and want to keep it as such) or whether you want to add a constructor to the class you can use different approaches.

const std::size_t rows = 26;
const std::size_t cols = 80;
struct Aggregate {
   char array[rows][cols];
};
class Constructor {
public:
   Constructor() {
      std::fill( &array[0][0], &array[rows][0], 0 ); // [1]
      // memset( array, 0, sizeof(array) );
   }
private:
   char array[rows][cols];
};
int main() {
   Aggregate a = {};
   Constructor b;
}

即使数组意味着是公共的,使用构造函数可能是一个更好的方法,因为它将保证数组在类的所有实例中正确初始化,而外部初始化对用户代码不要忘记设置初始值。

Even if the array is meant to be public, using a constructor might be a better approach as it will guarantee that the array is properly initialized in all instances of the class, while the external initialization depends on user code not forgetting to set the initial values.

[1]正如@Oli Charlesworth在评论中提到的,使用常量是一个不同的解决方案,状态(并保持同步)大小在多个地方。我在这里使用了一种不同的组合:通过请求第一列的地址超过二维数组一行,可以获得二维数组之外的第一个字节的指针。我使用这种方法只是为了表明它可以做,但它不比任何更好的& array [0] [0] +(rows * cols)

[1] As @Oli Charlesworth mentioned in a comment, using constants is a different solution to the problem of having to state (and keep in synch) the sizes in more than one place. I have used that approach here with a yet different combination: a pointer to the first byte outside of the bidimensional array can be obtained by requesting the address of the first column one row beyond the bidimensional array. I have used this approach just to show that it can be done, but it is not any better than others like &array[0][0]+(rows*cols)

这篇关于什么是安全的方式来填充多维数组使用std :: fill?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆