C++11之基于范围的for循环

Posted 林夕07

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11之基于范围的for循环相关的知识,希望对你有一定的参考价值。

系列文章

C++11之正则表达式(regex_match、regex_search、regex_replace)

C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)

C++11之智能指针(unique_ptr、shared_ptr、weak_ptr、auto_ptr)浅谈内存管理

C++11之强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)

C++11之Lanbda表达式(匿名函数)

C++11之右值引用:移动语义和完美转发(带你了解移动构造函数、纯右值、将亡值、右值引用、std::move、forward等新概念)

C++11之委派构造函数

C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)

C++11之模板的别名

C++11之追踪返回类型

C++11之auto类型推导

C++11之decltype类型推导(使用场景、推导四规则、cv限定符)


目录


基于范围的for循环

C++98遍历方式

在C++98标准中,当我们遍历数组时,一般方法就是下标遍历和指针遍历。


	int arr[] =  1,2,3,5,6 ;

	// 下标遍历
	for(size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
	
		std::cout << arr[i] << " ";
	
	std::cout << std::endl;

	// 指针遍历
	int* p = arr;
	for(p = arr; p < arr + sizeof(arr) / sizeof(arr[0]); ++p)
	
		std::cout << *p << " ";
	
	std::cout << std::endl;

当然还有一种遍历方式,需要包含<algorithm>头文件的for_each遍历。参数依次是:起始地址、结束地址、回调函数。地址是左闭右开区间[begin,end)

#include <iostream>
#include <algorithm>

void print(const int& elem)

	std::cout << elem << " ";


// for_each遍历
std::for_each(arr, arr + sizeof(arr) / sizeof(arr[0]), print);
std::cout << std::endl;

C++11 范围遍历

上述的几种遍历方式的共同点就是都需要写明循环的一个范围。对于我们需要完整的遍历一个有范围的集合/数组时,完全可以让编译器自动计算出范围。因此C++11引入了基于范围的for循环

格式:for(迭代的变量:数组)

现在我们使用范围遍历对数组进行遍历。

	for(const int& e: arr)
	
		std::cout << e << " ";
	
	std::cout << std::endl;

然后我们可以在这里加入auto自动类型(C++11),遍历将会更加简单。

	for (const auto& elem : arr)
	
		std::cout << elem << " ";
	
	std::cout << std::endl;

但范围遍历不能适用于所有情况,范围遍历的条件就是循环迭代的范围必须是可确定的。例如stringarrayvectorlistmap等都是可以正常使用的。而用户自定义写的类则需要自行提供自增运算符重载赋值运算符重载

	int* ptr = arr;
	for(auto elem : ptr)
	
		std::cout << elem << " ";
	
	std::cout << std::endl;

遍历没有明确范围的数组,是不能使用范围遍历方法的。

在使用范围遍历的方式遍历stl的容器时,如果你使用auto声明迭代器的变量,那么推导出来的类型是迭代器解引用后的对象。

	std::vector<int> vec 1,5,6,9,4 ;

	for (const auto iter = vec.begin(); iter != vec.end(); ++iter)
	
		std::cout << *iter << " ";
	
	std::cout << std::endl;

	for(const auto& elem : vec)
	
		std::cout << elem << " ";
	
	std::cout << std::endl;

这里就需要注意了前者iter类型是迭代器对象,后者elem是解引用后的对象。

以上是关于C++11之基于范围的for循环的主要内容,如果未能解决你的问题,请参考以下文章

C++11 反向基于范围的 for 循环

C++11 基于范围的for循环

在 Qt 中正确使用 C++11 基于范围的 for 循环

[C++11]基于范围的for循环

如何让 C++0x / C++11 风格的基于范围的 for 循环与 clang 一起使用?

C++11新特性:14—— C++11 for循环(基于范围的循环)详解