循环基于无法识别的范围
Unrecognized range-based for loop?
为什么这段代码:
void printarray(int array[]) {
for (int x: array) {
std::cout << x << std::endl;
}
}
是否生成此编译时错误?
error: 'begin' was not declared in this scope
for (int x: array) {
关于基于范围的for
循环,我做错了什么?
您的问题是array
实际上不是一个数组。当你写
void printarray(int array[])
它与相同
void printarray(int* array)
由于在没有额外大小参数的情况下无法判断指针指向多少元素,因此无法将其用于基于范围的for循环。
您需要做的是通过引用传递数组,这样数组就不会衰减为指针。如果你知道阵列的确切大小,那么你可以使用
void printarray(int (&array)[size_you_want_here])
如果你想让函数更通用,这样它就可以使用不同大小的数组,那么你可以使用这样的模板
template<std::size_t N>
void printarray(int (&array)[N])
在以上两种情况下,您现在都有一个实际的数组而不是指针,这样您就可以将它与基于范围的for循环一起使用。
还要注意,我们可以使用使函数完全通用
template<typename T, std::size_t N>
void printarray(T (&array)[N]) {
for (auto&& x : array) {
std::cout << x << "n";
}
}
您还会注意到我将std::endl
更改为"n"
。通常您不希望使用endl
,因为它在流上显式调用flush()
。一般来说,"n"
就是您所需要的,最后如果输出仍然没有刷新,那么您可以自己调用flush()
。
当数组作为函数的参数通过值传递时,它会隐式转换为指向其第一个元素的指针。声明数组的参数也会调整为指针。
例如,这些函数声明
void printarray( int array[100] );
void printarray( int array[10] );
void printarray( int array[] );
声明了相同的一个函数,相当于
void printarray( int *array );
因此,您还需要将数组的大小传递给函数,例如
void printarray( const int array[]. size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
std::cout << a[i] << std::endl;
}
}
您可以为通过引用传递的数组编写一个模板函数,例如
template <size_t N>
void printarray( const int ( &array )[N] )
{
for ( int x : array)
{
std::cout << x << std::endl;
}
}
或
template <typename T, size_t N>
void printarray( const T ( &array )[N] )
{
for ( auto x : array)
{
std::cout << x << std::endl;
}
}
然而,与以前的函数相比,它有一个缺点,因为不同大小的数组是不同的类型,编译器将从模板中生成与函数一起使用的不同类型的数组一样多的函数。
您可以使用标准算法,例如std::copy
或std::for_each
来输出数组。
例如
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::copy( std::begin( array ), std::end( array ),
std::ostream_iterator<int>( std::cout, "n" ) );
return 0;
}
另一种方法是使用标准类std::array
,其具有由基于范围的for语句使用的适当成员函数begin
和end
。例如
#include <iostream>
#include <array>
const size_t N = 10;
void printarray( const std::array<int, N> &array )
{
for ( int x : array ) std::cout << x << std::endl;
}
int main()
{
std::array<int, N> array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
printarray( array );
return 0;
}
但在这种情况下,如果要输出具有不同数量或类型元素的std::array
类对象,则还需要编写一个模板函数。
例如
#include <iostream>
#include <array>
template <typename T, size_t N>
void printarray( const std::array<T, N> &array )
{
for ( auto x : array ) std::cout << x << std::endl;
}
int main()
{
std::array<int, 10> array1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
printarray( array1 );
std::array<char, 10> array2 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
printarray( array2 );
return 0;
}
printarray接收的参数实际上是一个int*,的范围不知道在哪里停止。在这种情况下,您需要将长度作为参数发送,并对进行定期检查
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 提升 ASIO 无法识别计时器对象
- 从udp接收帧对于人脸识别来说太慢
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 模板类无法识别友元运算符
- 在基于范围的for循环中使用结构化绑定声明
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 如何识别范围
- 循环基于无法识别的范围
- 人脸识别器未在此范围内声明
- 如何在庞大的二进制数据中快速识别 1(索引)的连续范围
- 识别posix读取暂停在微秒范围内
- 循环的范围识别错误的类型(C2440)