【问题标题】:What's the STL way to fill a 2-dimensional std::array without iteration?无需迭代即可填充二维 std::array 的 STL 方法是什么?
【发布时间】:2017-12-08 10:52:47
【问题描述】:

我有一个二维的std::array std::arrays,我想用 0 填充它。我找到的唯一解决方案是使用指向第一个元素和sizeof 的指针,如下所示:

std::fill(&arr2d[0][0], &arr2d[0][0] + sizeof(arr2d), 0);

虽然它有效,但它与我发现的用于填充 1D std::arrays 而不使用指针逻辑的其他方法不一致,例如以下两个:

std::fill(arr1d.begin(), arr1d.end(), 0);
arr1d.fill(0);

我可以遍历每个数组,如下所示:

for (auto& it : arr2d) {
    it.fill(0);
}

但似乎一次填充数组会更有效率。二维数组有没有更简洁的方法,还是我坚持使用 C 风格的指针逻辑?

【问题讨论】:

  • 你为什么认为std::fill 不会推出类似的循环。如果您希望填写 0,则可以使用 std::memset
  • @DeiDei 我的 C++ 编程目标之一是避免像 memset 这样的 C 风格逻辑。我不认为std::fillstd::memset 会或不会像我的示例那样滚动循环。我相信实现编写者是比我更好的程序员,并且根据需要进行了优化。
  • 1.数组元素类型是什么? 2. 填0还是任意值?
  • std::fill(arr2d.begin(), arr2d.end(), decltype(arr2d)::value_type{0})arr2d.fill(decltype(arr2d)::value_type{0})。随意拼出实际类型来代替decltype(arr2d)::value_type;当你选择隐瞒arr2d的声明时,你让我别无选择,只能从事这些赞美诗
  • @IgorTandetnik 感谢您的回答。有问题的数组的类型是BYTE,实际上是std::uint8_t 的类型别名。不幸的是,你给我的答案都没有奏效。使用std::fill 给我一个神秘的STL 错误,而使用std::array::fill 给我error: no matching function for call to 'std::array<std::array<unsigned char, 32ul>, 64ul>::fill(BYTE)'

标签: c++ arrays c++11 multidimensional-array stl


【解决方案1】:

在您的情况下,只需使用 {} 分配(或初始化):

using arr2d_t = std::array<std::array<unsigned char, 32>, 64>;
arr2d_t arr2d = {}; // all zeroes

arr2d = {}; //ditto

【讨论】:

  • 这不是我想要的。我想在初始化后清空数组。
  • 所以分配{}给它。
  • 哦,对不起。我不知道你能做到!
  • @robbie0630 你不能清空std::array
【解决方案2】:

我想提出一个 T.C. 答案的变体,它在处理非常大的数组时很有用。

在使用面向 C++ 14 的 Visual Studio 2019(v142 工具)时,我发现使用 {} 进行零初始化会使用编译器生成的临时变量,该变量会消耗堆栈空间,即使数组本身不在堆栈上也是如此:

std::array<std::array<double, 1024>, 1024> myArray;

int main(int argc, char* argv[])
{
    myArray = {}; // <- all zeros but consumes 8,388,608 bytes of stack
    return 0;
}

通过存储匹配类型的零初始化数组的静态副本,您可以在以后随时将静态副本分配或重新分配给感兴趣的数组,编译为单个 memcpy 调用:

std::array<std::array<double, 1024>, 1024> myArray;

int main(int argc, char* argv[])
{
    static const std::array<std::array<double, 1024>, 1024> EmptyArray = {}; // all zeros
    myArray = EmptyArray; // all zeros
    return 0;
}

【讨论】:

    猜你喜欢
    • 2021-07-27
    • 2021-10-30
    • 2020-04-18
    • 2017-05-22
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多