【问题标题】:Getting 'Non-constant expression as array bound' when field is const当字段为 const 时获取“非常量表达式作为数组绑定”
【发布时间】:2013-06-19 18:26:19
【问题描述】:

我正在尝试使用我的常量字段作为其维度来定义一个多维数组,但我收到一个编译错误,指出表达式不是常量。有没有其他方法可以使用构造函数初始化列表中定义的常量字段作为数组维度?

为说英语的大多数人翻译:

class FunctionWave2D : public DisallowedDomainPoints
{
protected:
    double th; 
    double l; a
    double d, dd; 
    const int number_sqrt;  //here's the constant

    double **second_derivatives;

protected:
    bool elasticTenstionOnly;

public:
    FunctionWave2D(int number, double elasticModulus, double dampingFactor, double oscillationDampingFactor, double length)
        :DisallowedDomainPoints(number * LAYER_COUNT),
        th(elasticModulus), d(dampingFactor), dd(oscillationDampingFactor),
        elasticTensionOnly(false),
        l(length/(sqrt(number)-1)),
        number_sqrt(sqrt(number))
    {   
        second_derivatives = new double[number_sqrt][number_sqrt][LAYER_COUNT];
//(...)

【问题讨论】:

  • @AJMansfield 它可能是本地语言,而不是被混淆
  • (我认为是波兰语)
  • @AJMansfield 变量是合理的,它是波兰语。虽然它们很长
  • @ShamimHafiz 我猜你可能是对的。不过名字还是不好。
  • 好的,各位,我已经编辑了我的评论。

标签: c++ arrays multidimensional-array


【解决方案1】:

数组绑定必须是编译时常量。非静态 const 数据成员不是编译时常量;它在运行时获取它的值,当对象被构造时。

因此,基本上,如果您需要在运行时设置该数组的大小,则必须使用operator new[] 构建所有部分。本质上,

int **data_2d = new int*[runtime_size];
for (int i = 0; i < runtime_size; ++i)
    data_2d[i] = new int[runtime_size];

3d 数组的扩展很简单。

【讨论】:

    【解决方案2】:

    在 C++ 中,术语“常量表达式”专门指其值在编译时已知的表达式。它与 const 变量不同。例如137是一个常量表达式,但是在这段代码中:

    int function(int x) {
        const int k = x;
    }
    

    k 的值不是常量表达式,因为它的值无法在编译时确定。

    在您的情况下,您有一个数据成员声明为

     const int ilosc_sqrt;  //here's the constant
    

    即使这被标记为const,它的值在编译时是未知的。它在初始化列表中被初始化为

    ilosc_sqrt(sqrt(ilosc))
    

    在程序实际运行之前无法确定该值,因此会出现错误。 (请注意,新的 C++11 constexpr 关键字旨在使常量表达式更容易在源代码中识别,并可以使用常量进行更高级的编译时计算。)

    要解决此问题,您需要将初始化拆分为更小的步骤:

    drugie_pochodne = new double**[ilosc_sqrt];
    for (int i = 0; i < ilosc_sqrt; i++) {
        drugie_pochodne[i] = new double*[ilosc_sqrt];
        for (int j = 0; j < ilosc_sqrt; j++) {
            drugie_pochodne[j] = new double[ILOSC_WARSTW];
        }
    }
    

    或者使用像 Boost.MultiArray 这样的库,它支持更简洁的初始化语法。

    希望这会有所帮助!

    【讨论】:

    • 谢谢你,我不知道,你为我省去了很多无意义的调试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 2012-02-23
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多