range-based for loop

1. 基于范围的for循环语法

C++11标准引入了基于范围的for循环特性,该特性隐藏了迭代器
的初始化和更新过程,让程序员只需要关心遍历对象本身,其语法也
比传统for循环简洁很多:

for ( range_declaration : range_expression )
{
    loop_statement;
}

基于范围的for循环不需要初始化语句、条件表达式以及更新表达式,取而代之的是一个范围声明和一个范围表达式。其中范围声明是一个变量的声明,其类型是范围表达式中元素的类型或者元素类型的引用。而范围表达式可以是数组或对象,对象必须满足以下2个条件中的任意一个。
    1.对象类型定义了begin和end成员函数。

    2. 定义了以对象参数为类型的begin和end普通函数。

#include <iostream>
#include <string>
#include <map>
std::map<int, std::string> index_map{ {1, "hello"}, {2, "world"},
{3, "!"} };
int int_array[] = { 0, 1, 2, 3, 4, 5 };
int main()
{
    for (const auto &e : index_map)
    {
        std::cout << "key=" << e.first << ", value=" << e.second <<
        std::endl;
    }

    for (auto e : int_array)
    {
        std::cout << e << std::endl;
    }
}

如果不会在循环过程中修改引用对象,那么推荐在范围声明中加上const限定符以帮助编译器生成更加高效的代码:
 

#include <iostream>
#include <vector>

struct X
{
    X() { std::cout << "default ctor" << std::endl; }
    X(const X& other)
    {
        std::cout << "copy ctor" << std::endl;
    }
};

int main()
{
    std::vector<X> x(10);
    std::cout << "for (auto n : x)" << std::endl;
    for (auto n : x)
    {
    }
    std::cout << "for (const auto &n : x)" << std::endl;
    for (const auto &n : x)
    {
    }
}

输出:

default ctor
default ctor
for (auto n : x)
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
for (const auto &n : x)

2. 实现自己的range-for

//since C++17, until C++20

for (range-declaration : range-expression )
{
    loop-statement
}

The above syntax produces code equivalent to the following except for the lifetime expansion of temporaries of range-expression.
{
    auto && __range = range-expression ;  //gcc
    //auto &_range = range-expression;   //clang
    auto __begin = begin-expr ;
    auto __end = end-expr ;
    for ( ; __begin != __end; ++__begin)
    {
          range-declaration = *__begin;
          loop-statement
    }
}

其中operator *用于编译器生成解引用代码,operator !=用于生成循环条件代码,而前缀版本的operator ++用于更新迭代器。

#include <iostream>

template<typename T, size_t L>
class Iter
{
public:
    Iter(T* data, size_t idx):data{data}, idx{idx}{}

    T& operator*()
    {
        return *(data + idx);
    }
    Iter& operator++()//前缀operator ++
    {
        idx++;
        return *this;
    }
    bool operator != (const Iter& other)
    {
        return other.idx != this->idx;
    }

private:
    size_t idx{0};
    T* data;
};

template<typename T, size_t L>
class array
{
public:
    using
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值