【问题标题】:no matching function for call to ‘begin(int**&)’调用“begin(int**&)”没有匹配的函数
【发布时间】:2014-12-14 03:24:00
【问题描述】:

我写了一个c++程序fllow(3.43.cpp):

#include <iostream>
using std::cout;
using std::endl;

void version_1(int **arr) {
    for (const int (&p)[4] : arr) {
        for (int q : p) {
            cout << q << " ";
        }
        cout << endl;
    }
}

int main() {
    int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    version_1(arr);
    return 0;
}

然后我使用:gcc my.cpp -std=c++11 编译它,有一个我无法处理的错误。 信息:

3.43.cpp:6:30: error: no matching function for call to ‘begin(int**&)’
     for (const int (&p)[4] : arr) {
                              ^
3.43.cpp:6:30: note: candidates are:
In file included from /usr/include/c++/4.8.2/bits/basic_string.h:42:0,
                 from /usr/include/c++/4.8.2/string:52,
                 from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
                 from /usr/include/c++/4.8.2/bits/ios_base.h:41,
                 from /usr/include/c++/4.8.2/ios:42,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from 3.43.cpp:1:
/usr/include/c++/4.8.2/initializer_list:89:5: note: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)
     begin(initializer_list<_Tp> __ils) noexcept

我在谷歌搜索,但没有找到类似的答案。

【问题讨论】:

  • passing 2D array to function。此外,您在致电version_1...
  • 把参数类型改成const int (&amp;arr)[3][4],把其他两个参数去掉。
  • 基于范围的 for 循环只能用于 std::begin(x)std::end(x) 有效的对象
  • @quantdev 我删除了本地程序中的 aguments,但在这里要删除,我已经更改了它。谢谢!
  • 为什么不使用一些理智的东西……比如矢量?

标签: c++ arrays c++11 compilation


【解决方案1】:

由于arr 只是一个指针,因此无法推断它有多大。但是,由于您实际上是在传递一个真正的数组,因此您可以在函数的维度上对其进行模板化,这样您就可以通过引用获取实际的数组,而不是让它衰减到一个指针:

template <size_t X, size_t Y>
void foo(const int (&arr)[X][Y])
{
    std::cout << "Dimensions are: " << X << "x" << Y << std::endl;

    for (const int (&row)[Y] : arr) {
        for (int val : row) {
            std::cout << val << ' ';
        }
        std::cout << std::endl;
    }
}

int main() {
    int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    foo(arr);
}

【讨论】:

  • 当然,循环变量的类型说明符可以替换为auto &amp;
  • @MattMcNabb 是的,但为了清楚起见,我想说明 OP 的类型。
  • 基于for的范围相当于从开始(容器)到结束(容器)的迭代。请注意,不需要 std::。函数 begin 和 end 需要定义
  • @Shooter 好点,实际上标准说:“begin-expression 和 end-expression 分别是 begin(__range) 和 end(__range),其中 begin() 和 end() 函数使用参数相关查找 (ADL) 其中还包括标准命名空间进行查找。"它包含 std 命名空间可能是因为 std::beginstd::end 是为常规 C 样式数组定义的。
【解决方案2】:

std::begin()std::end() 不适用于指针。它们仅适用于数组。如果您想推断数组的大小,您需要将其作为引用传递给您的函数:

#include <cstddef>
template <std::size_t A, std::size_t B>
void version_1(int (&arr)[B][A]) {
    for (const int (&p)[A] : arr) {
        for (int q : p) {
            cout << q << " ";
        }
        cout << '\n';
    }
}

【讨论】:

    【解决方案3】:

    指针与数组不同。为了能够使用基于范围,您的容器必须支持std::beginstd::end。可以使用标准 C 数组,但不能使用指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 2013-01-08
      • 2020-07-02
      相关资源
      最近更新 更多