【问题标题】:Fixed sized multidimensional array arguments固定大小的多维数组参数
【发布时间】:2023-04-03 14:51:01
【问题描述】:

我正在用 C++ 编写一个通用矩阵类。我希望能够从二维双精度数组初始化矩阵。因为我使用的是模板,因此在编译时需要知道矩阵大小,我想确保只有给定大小的数组可以传递给构造函数。用代码表示为:

template<unsigned int M, unsigned int N>
class Matrix {
public:
    Matrix(double (&values)[M][N]);
}

现在,奇怪的部分来了:正如预期的那样,下面的代码就像一个魅力:

    double arr [3][3] = { {1,2,3},
                          {1,2,3},
                          {1,2,3} };
    Matrix<3,3>* mat3x3p = new Matrix<3,3>(arr);

但是当匿名传递数组时,代码被破坏了:

Matrix<3,3>* mat3x3p = new Matrix<3,3>({ {1,2,3},
                                         {1,2,3},
                                         {1,2,3} });

这同样适用于通过赋值构造。 确切的错误信息是:

no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘double (&)[3][3]’

【问题讨论】:

  • 试试Matrix(double (&amp;values)[][N]);
  • 对不起,我的错。但是,Matrix(const double (&amp;values)[M][N]); 应该可以工作。

标签: c++ arrays templates constructor multidimensional-array


【解决方案1】:

这会将临时绑定到对非const 的(左值)引用,这是不允许的。如果您更改为对const 的引用,那么这将起作用——尽管在数组的情况下它有点奇怪,因为 cv-限定符适用于元素类型,而不是数组本身。尽管如此,如果你有

Matrix(const double (&values)[M][N]);

然后

Matrix<3, 3>({{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }})

在 C++11 中有效,这要归功于列表初始化。我不知道如何让它适用于 C++03。

【讨论】:

  • 有趣,虽然添加 const 限定符修复了构造函数问题,但仍然无法赋值
  • @Paranaix 当您遇到这种情况时,请始终尝试添加一个大括号级别。 IE。 m = {{{ 1, 2, 3 }}, { 4, 5, 6 }, { 7, 8, 9 }}}。新级别的大括号​​用于Matrix&lt;3, 3&gt;,因此相当于m = Matrix&lt;3, 3&gt; {{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }}
  • 不幸的是,这不起作用。我认为我应该将构造函数声明为“显式”,以便清楚地表明转换构造函数是不可能的。
  • 将大括号括起来的列表转换为数组解决了问题: Matrix mat3x3 = (double[3][3]) {{1,1,1},{2,2 ,2},{3,3,3}};
  • @Paranaix 这可能意味着你已经达到了编译器的极限。您是否尝试过明确写 operator=const int (&amp;)[M][N]
【解决方案2】:

根据 C++ 标准初始值设定项列表只能存在于变量声明中。虽然多了几行代码,但在编译后,您的第一个示例应该不会比第二个更多。

【讨论】:

    猜你喜欢
    • 2013-01-24
    • 2012-03-17
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2019-02-10
    相关资源
    最近更新 更多