【问题标题】:How can I initialize 2d array with a list of 1d arrays?如何使用一维数组列表初始化二维数组?
【发布时间】:2019-01-09 15:56:29
【问题描述】:

如何使用一维数组列表初始化二维数组?

void main()
{
    int a[] = { 1,2,3 };
    int b[] = { 4,5,6 };
    int array[][3] = { a,b };
}

【问题讨论】:

  • 请注意,在 c++ 中,main 必须具有返回类型 int,即使您从未使用过 return
  • @FrançoisAndrieux:我的视觉工作室没有抱怨。我正在使用 c++17。
  • Visual Studio 不会抱怨很多事情。所有编译器和 IDE 也是如此。首先是因为该语言不需要编译器来诊断所有类型的错误,还因为许多平台提供了默认扩展,这些扩展不是最好的可移植,最坏的情况是不兼容。事实上,语言定义的main的形式都需要c++中的返回类型int。关于main 需要注意的一点是,任何平台都可以定义他们想要的任何形式的main,包括返回void 的那些,尽管它们根据定义是不可移植的。

标签: c++ arrays multidimensional-array


【解决方案1】:

C++ 中的原始数组是一种二等公民。它们不能被赋值也不能被复制,这意味着你不能用它们来初始化其他数组,而且它们的名字在大多数情况下会衰减为一个指针。

Lucky C++11 提供了一个解决方案。 std::array 就像一个原始数组,但它没有缺点。您可以使用它们来构建一个二维数组,例如

std::array<int, 3> foo = {1,2,3};
std::array<int, 3> bar = {3,4,5};
std::array<std::array<int, 3>, 2> baz = {foo, bar};

如果你有 C++17 支持,你可以利用 class template argument deduction 摆脱必须指定模板参数的麻烦,代码简化为

std::array foo = {1,2,3};
std::array bar = {3,4,5};
std::array baz = {foo, bar};

你可以看到在这个live example工作

【讨论】:

  • 它在这种情况下有效,但要注意这种初始化可能(有时必须)发生的直观事情。如果您还没有foobar,则必须编写std::array&lt;std::array&lt;int, 3&gt;, 2&gt; array = { 0, 1, 2, 3, 4, 5 };,而不是... = { { 0, 1, 2 }, { 3, 4, 5 } };(后者无法编译)!
  • @MaxLanghof 你也可以使用std::array test = {std::array{1,2,3},std::array{3,4,5}}
  • 不幸的是,CTAD 不能(但希望)通过 using 指令来缩短名称 :(
【解决方案2】:

使用std::array

auto a = std::array{ 1,2,3 };
auto b = std::array{ 4,5,6 };
auto array = std::array{ a,b };

Demo

【讨论】:

    【解决方案3】:

    您呈现的方式 - 根本不是...您可以:

    int array[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
    

    如果您仍然需要 a 和 b,则可以将它们作为指针:

    int* a = array[0];
    int* b = array[1];
    

    或者更接近你最初的尝试:对数组的引用:

    int(&a)[3] = array[0];
    int(&b)[3] = array[1];
    

    这样,你仍然可以 e. G。将sizeof 应用于ab...

    或者反过来:创建一个指针数组

    int a[] = { 1,2,3 };
    int b[] = { 4,5,6 };
    int* array[] = { a, b };
    

    到目前为止,所有这些解决方案都有一个共同点,即 a 和 array[0] 访问完全相同的数据。如果您实际上想要两个 独立 副本,则无法将数据从一个副本复制到另一个副本,例如。 G。通过std::copy

    如果您从原始数组切换到 std::array,您可以直接进行这种初始化(带有副本):

    std::array<int, 3> a;
    std::array<int, 3> b;
    std::array<std::array<int, 3> 2> array = { a, b };
    

    【讨论】:

      【解决方案4】:

      std::array 是这里的方法,但是如果你想坚持语言的方式(而不是标准库),并且你的组合数组与其成分具有相同的生命周期,并且如果数据可以共享,你可以有一个指向数组的指针数组并说

      int a[] { 1,2,3 };
      int b[] { 4,5,6 };
      
      decltype(a) *abArr[] {&a, &b};
      // equivalent to 
      // int (*abArr[])[3] { &a, &b };
      

      请注意,这不是二维数组,其元素也不是整数。 但是您仍然可以通过两个维度进行范围循环,因为指针是指向固定大小数组的真正指针(而不是由于数组衰减而导致的单纯 int 指针,不能进行范围循环)。

      由于数组元素是指针,因此需要取消引用row

      for (auto const& row : abArr)
          for (auto const& e : *row)
              cout << e << " ";
      

      现场示例:http://coliru.stacked-crooked.com/a/cff8ed0e69ffb436

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 2011-12-08
        • 2012-11-29
        • 1970-01-01
        相关资源
        最近更新 更多