技术问询:能否将作为参数传递的数组用于std::begin或std::end?
问题根源
你遇到的核心问题是数组作为函数参数时会自动退化为指针。C++中,当你写int ints[]作为函数参数,编译器实际会把它等价处理成int* ints——此时ints已经不是带大小信息的数组类型,而是普通指针。而std::begin/std::end需要依赖数组的大小信息来生成迭代器,直接给指针调用这两个函数自然会编译报错。
你之前尝试强制转换为&int[0]行不通,因为指针本身没有数组大小的元信息,编译器无法从指针恢复出原来的数组类型,强制转换也补不回丢失的大小数据。
解决方案
方案1:直接用指针构造迭代范围(适配所有C++版本)
既然你已经手动传递了size参数,完全可以跳过std::begin/std::end,利用指针本身就是随机访问迭代器的特性:
#include <iostream> #include <algorithm> using namespace std; class Test { public: static bool exists(int ints[], int size, int k) { return std::find(ints, ints + size, k) != ints + size; } };
这个写法最简洁,不需要修改参数结构,兼容所有C++标准。
方案2:用模板函数自动推导数组大小(无需手动传size)
如果不想手动传递数组长度,可以把函数改成模板,让编译器自动推导数组的大小:
#include <iostream> #include <algorithm> using namespace std; class Test { public: template <size_t N> static bool exists(int (&ints)[N], int k) { return std::find(std::begin(ints), std::end(ints), k) != std::end(ints); } }; // 调用示例: // int arr[] = {1,2,3}; // Test::exists(arr, 2);
这里用了数组引用参数int (&ints)[N],避免了数组退化,编译器能自动推导出数组的大小N,因此可以正常使用std::begin/std::end。
方案3:用std::span(C++20及以上推荐)
如果你的项目支持C++20,std::span是最优雅的解决方案——它是一个轻量级的范围视图,既能包裹数组,也能适配指针+大小的组合,同时保留范围信息:
#include <iostream> #include <algorithm> #include <span> using namespace std; class Test { public: static bool exists(std::span<int> ints, int k) { return std::find(ints.begin(), ints.end(), k) != ints.end(); // C++20还可以用更简洁的范围写法: // return std::ranges::find(ints, k) != ints.end(); } }; // 调用示例: // int arr[] = {1,2,3}; // Test::exists(arr, 2); // 也可以直接传指针+大小: // Test::exists({arr, 3}, 2);
内容的提问来源于stack exchange,提问作者leto
相关产品推荐
相关产品推荐

