【问题标题】:C++ error from passing an integer array as a parameter将整数数组作为参数传递的 C++ 错误
【发布时间】:2018-05-31 17:41:27
【问题描述】:

跟进Range-for-statement cannot build range expression with array function parameter

原来的错误是:

错误:无法使用数组函数参数“arr”构建范围表达式,因为数组类型“int []”的参数被视为指针类型“int *”

失败的代码:

void print(int (&arr)[int]){
    for(int x: arr)
        cout<<" "<<x;
    cout<<endl;
}

固定代码:

template<int N>
void print(int (&arr)[N]){
    for(int x: arr)
        cout<<" "<<x;
    cout<<endl;
}

我的问题是,为什么我们必须这样修复它?我不明白int (&amp;arr)[int] 是什么意思。

【问题讨论】:

  • 为什么这样可以修复错误?因为第一个示例不是有效的 c++ 而第二个示例是。我不清楚你到底在问什么。
  • “如何理解int (&amp;arr)[int]?”作为无效语法。
  • 哪个编译器为您提供了第一个代码 sn-p 的错误消息?我已经通过 GCC、Clang 和 MSVC 运行了它,它们三个都给出了关于 [int] 的错误
  • 我使用了 g++ -std=c++11。

标签: c++ arrays


【解决方案1】:

您的问题有点令人困惑,因为您的第一个示例不是有效代码。

但是,我认为这里仍然需要提供一个解释。这是您的第一个函数的“正确”版本:

void print(int (&arr)[5]){
    for(int x: arr)
        cout<<" "<<x;
    cout<<endl;
}

void foo() {
    int x[5];
    int y[3];

    print(x);
    print(y); // Bam! error!
}

print() 函数将 5 个整数的数组作为参数。请注意,这只能使用静态大小的数组来完成。 编译函数时编译器必须知道数组的大小,并且该函数仅适用于特定的数组大小。

让我们将其与您的第二个有效示例进行对比。

单个数组大小,这有点烦人。如果我不想为各种数组大小编写不同的函数怎么办?我们总是可以传递一个指针和一个大小,但这有点难看(更不用说容易出错了)。

相反,我们可以给编译器一个函数模板。也就是说,不是函数,而是如何按需创建函数的秘诀。

template<int N>
void print(int (&arr)[N]){
    for(int x: arr)
        cout<<" "<<x;
    cout<<endl;
}

常量5 已被placeholder constant N 替换(必须是int,如模板声明中所指定。这样,编译器将为每个生成一个单独的print() 函数我们称之为数组大小。

【讨论】:

  • 你的意思是如果我们声明一个带有数组作为输入的函数,我们必须指定数组大小,因为编译器必须知道数组大小?是否也是因为数组不是动态调整大小的?
  • @LushaLi “指定数组大小,因为编译器必须知道数组大小?”是的。为了使用基于范围的for 循环,编译器需要知道大小才能知道在哪里停止。 “也是因为数组不是动态调整大小的吗?”不,动态分配实际上会使情况变得更糟,因为没有办法从指针推断数组的大小。真正的问题是数组在传递给函数时会衰减为指针。更多信息在这里:What is array decaying?
【解决方案2】:

这背后的基本原理是 C++ 只允许 constepr 用于数组维度。模板版本确保 N 是一个 constepr(编译时间常数),而不正确的版本让您认为您打算使用运行时间整数值作为数组大小 - 不幸的是,这在 C++ 中是被禁止的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2016-06-12
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多