【问题标题】:Passing two-dimensional arrays of varying size in c++在 C++ 中传递不同大小的二维数组
【发布时间】:2012-02-28 21:46:12
【问题描述】:

我正在尝试以可变大小的二维数组作为参数调用函数。为此,我使用了一个模板:

template <int N, int M>
void move(int (&arr)[M][N]);

现在,当我直接声明数组的大小时,这可以正常工作,例如:

int arr[5][7];
move(arr);

但如果我从其他地方获取尺寸,例如:

int x, y;
x = 7;
y = 5;
int arr[y][x];
move(arr);

编译器显示此错误:

没有匹配函数调用'move(int[((unsigned int)((int)y))][((unsigned int)((int)x))])

...我不明白。我对 c++ 相当陌生,这可能只是我很愚蠢,而且我知道 c++ 中的多维数组很有趣,但在这种情况下,我什至不明白问题出在哪里。有人有想法吗?

编辑:我奇怪地措辞了这个问题,对此感到抱歉 - 数组本身不会改变它的大小,但该函数应该能够处理不同大小的数组。问题是为什么当我直接声明数组的大小时有效,但当我声明每个维度的参数然后用这些声明数组时无效。

【问题讨论】:

  • C++ 中的数组具有固定的编译时常量大小。没有“不同大小的数组”这样的东西。它只是不存在。请改用vector,或者使用 Boost.multiarray。
  • 我的措辞可能很奇怪 - 数组本身不会改变它的大小,但该函数应该能够处理不同大小的数组。我会快速编辑它。
  • 好的,但请注意,也没有动态确定大小的数组(类型)之类的东西。对不起。您必须手动或通过 std::vector 等容器管理动态数组。
  • 同意@KerrekSB,但是如果你想使用“手动”数组,至少要声明一个类来处理它们,比如template &lt;class T&gt; class BidimensionalArray,带有T**类型的支持变量。
  • @KerrekSB:嗯,它们作为编译器扩展存在于 g++ 中。但它们不是标准 C++ 的一部分,不。如果“没有这样的事情”,编译器会在声明数组时给 OP 一个错误。但是当它尝试扩展模板(绝对不会处理非常量参数)时会给出错误。实际上,当它尝试扩展模板时,它没有段错误或类似的东西给我留下了深刻的印象。

标签: c++ multidimensional-array


【解决方案1】:

像这样声明一个具有变量边界的数组首先是一个扩展。它实际上不是有效的标准 C++。其次,不赞成在 C++ 中使用裸数组。你应该改用::std::vector

编译器错误信息实在是太难理解了。我很高兴它能够给你一个而不是出错。您正在向它展示一个非常奇怪的案例。

模板参数必须是编译时常量。它们不能是其值可能在运行时发生变化的事物。编译器必须有可能知道参数在编译时是常量。仅当值是实际文字值或声明为 constexpr 的命名值或涉及声明为 constexpr 的文字或值的简单表达式时,才会发生这种情况。

如果您的数组带有变量边界...这些变量都不是constexprs,因此它们可能会在运行时发生变化。编译器无法提前知道要生成哪个版本的函数。

【讨论】:

    【解决方案2】:

    因为,尽管您为 xy 提供了静态已知值,但它们都是可变变量,因此,它们仍然不符合数组维度的标准。那么模板函数就不能以这种奇怪的方式实例化。

    const unsigned int x = 7, y = 5;
    

    这就够了。

    使用静态已知量以外的任何东西(例如文字,如上所述)初始化 const unsigned int不会

    constexpr 让 C++11 中的数组维度安全更容易保证。

    【讨论】:

      猜你喜欢
      • 2013-07-15
      • 2021-12-15
      • 2017-07-26
      • 2011-05-24
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多