C++ 指针上的开始/结束 (arr) - 调用 'begin(int**&)' 没有匹配函数
C++ begin/end(arr) on a pointer - no matching function for call to ‘begin(int**&)’
>我想获取数组的长度。我有这个代码:
#include <iterator>
#include <iostream>
#include <string>
using namespace std;
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int main() {
printArrLen(testArr);
cout << "main/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
cout << end(testArr) << endl;
}
void printArrLen(int arr[]) {
cout << "printArrLen/arr; Memory address: " << arr << ", value: " << *arr << endl;
cout << "printArrLen/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
// This works:
cout << end(testArr) << endl;
// This doesn't work - no matching function for call to 'end(int*&)':
// cout << end(arr) << endl;
// Doesn't work:
// cout << "arrLen: " << end(arr) - begin(arr) << endl;
}
输出:
printArrLen/arr; Memory address: 0x601318, value: 1
printArrLen/testArr; Memory address: 0x601318, value: 1
0x601324
main/testArr; Memory address: 0x601318, value: 1
0x601324
在printArrLen中取消注释cout << end(arr) << endl;
给出了no matching function for call to 'end(int*&)'
我知道如果arr
是一个指针,begin/end(arr)
行不通。 为什么他们在 printArrLen 和 main 中的 testArr 上工作,如果 testArr 似乎也是一个指针?如何在printArrLen中证明testArr
不是指针,而arr
是指针,而它们似乎都包含内存地址?
如果 arr 是一个指针,开始/结束(arr) 将不起作用。为什么他们在 printArrLen 和 main 中的 testArr 上工作,如果 testArr 似乎也是一个指针?
指针不是数组。
在您的代码中,
testArr
是已用 3 个元素初始化的数组。arr
是数组参数。数组参数的特殊之处在于数组decays
指针,因此实际传递给函数printArrLen
的是一个指针(指向第一个元素arr
)。
顺便说一句,初始化时不必提供数组大小。这也行(而且更好):
int testArr[] = {1, 4, 5};
我想得到一个数组的长度。
[...]
void printArrLen(int arr[]);
不是这样的。 此函数中的arr
实际上是指向数组第一个元素的指针。或者更准确地说,它可能指向数组的第一个元素。这只是一个int*
,可以指向任何地方。无论如何,函数内部不再有大小信息。你根本无法得到它。
[]
语法只是为了让您感到困惑。但是不要相信我的话 - 通过尝试这段代码来询问您的编译器:
void printArrLen(int arr[]) {}
void printArrLen(int* arr) {}
你会看到它会抱怨重新定义。
与
上面的arr
参数相反,
int testArr [3] = {1, 4, 5};
testArr
是一个数组,并在其类型中携带大小信息。int main() { printArrLen(testArr);
在这里你向函数传递一个指向testArr
第一个元素的指针,即指向 "1" 元素的int*
。
// This works: cout << end(testArr) << endl;
因为testArr
是一个数组。
// This doesn't work - no matching function for call to 'end(int*&)': // cout << end(arr) << endl;
因为arr
是一个指针。
如果数组的大小仅在运行时已知,请使用std::vector
,如果在编译时已知,则使用std::array
。两个容器始终知道自己的大小。
如何在 printArrLen 中证明
testArr
不是指针 当它们似乎都包含内存地址时,arr
?
这个问题没有看起来那么有意义。
考虑一下:
int main()
{
int i = 0;
double d = 0.0;
}
现在,你怎么能"证明"i
不是double
而是d
?
答案是你不必"证明"它,因为显然,你已经知道了。
从技术上讲,您的问题当然还有另一个答案,那就是使用typeid
......
#include <typeinfo>
#include <typeindex>
#include <iostream>
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int anotherTestArr [3] = {1, 4, 5};
int yetAnotherTestArr [4] = {1, 4, 5, 6};
int main() {
printArrLen(testArr);
}
void printArrLen(int arr[]) {
std::cout << (std::type_index(typeid(arr)) == std::type_index(typeid(testArr))) << "n";
std::cout << (std::type_index(typeid(anotherTestArr)) == std::type_index(typeid(testArr))) << "n";
std::cout << (std::type_index(typeid(yetAnotherTestArr)) == std::type_index(typeid(testArr))) << "n";
}
这对您没有任何直接用途,但它具有很大的教育价值。它将打印:
0
1
0
此示例演示不同大小的数组是不同的类型,指针是所有数组类型的不同类型。
testArr
不是一个指针,它是一个包含3
元素的数组。
arr
是一个指针 - 没有足够的知识来使begin
和end
工作,因为编译器不知道它指向一个数组(以及假设数组的大小)。
我的建议是:使用std::array
或std::vector
,具体取决于您需要做什么。如果要使用老式数组,请更改printArrLen
以采用数组引用:
template <size_t N>
void printArrLen(int (&arr)[N]) {
/* ... */
}
魔杖盒示例
- 调用'begin(int [n])'没有匹配函数
- 有没有函数可以在擦除 c++ 中获取 deque.begin() 的 int 值?
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量
- 使用 std::set 的 .begin() 和 .end() 函数会产生意想不到的结果
- 为什么 free 函数不能在 C 数组上运行,而 std::begin 在某些情况下可以在 C++14 中运行?
- 将模式包装为 std::begin; 返回 begin(c); 到函数中
- C++ 指针上的开始/结束 (arr) - 调用 'begin(int**&)' 没有匹配函数
- 如何使用begin()自由函数
- 成员函数 .begin() 和 std::begin()
- 非成员函数 begin()/cbegin() 及其 constexpr-ness
- 使用 C++11 的 begin() 和 end() 函数通过参数确定数组维度
- 调用 'begin(int**&)' 没有匹配函数
- 避免通用容器中 begin() 和 end() 函数的重复代码
- begin() 和 end() 函数不应该是模板类 Vector 的成员函数吗?
- 迭代一个STL容器,而不是从.begin()函数开始
- Iterator::Begin()函数错误
- 为我的向量包装器和迭代器返回'begin'和'end'函数返回什么?
- C++11 std::begin 不适用于传递给模板函数的 int[]
- 从特定位置调用Upper_bound函数,而不是使用data.begin()
- C++名为begin()问题的成员函数