博客如何优雅的写C++代码 Obotcha介绍(ForEveryone函数)

循环遍历一个容器的数据的时候,我们都会使用foreach的语法,或者类似python/rust语言中的for xxx in container的语法,这样用起来非常爽。由于我在obotcha里面自己实现了ArrayList等容器,每次遍历都需要用比较繁琐的iterator,代码如下:

auto ite = list->getIterator();
while(ite->hasValue()) {
    xxxxx;
    ite->next();
}

虽然逻辑上没有错误,但是整体代码看上去有很多重复代码,有点不舒服。所以想起了是不是可以实现类似的foreach语法。为了区别于foreach,我们在Obotcha里面定义了一个ForEveryOne的宏定义。具体使用如下:

ForEveryOne(value,list) {
    xxxxxx
}

粗粗看起来,是不是和foreach基本一样啦?哈哈,对比使用iterator的代码,是不是简单了很多?

关键ForEveryOne还支持并发操作,也就是说大括号里面的代码是线程安全的~。好的,现在我们看一下这个ForEveryOne的实现原理吧~

#define ForEveryOne(X,Y) \
    auto X##__m_lock = __forEveryOneAcquireLock(Y);\
    decltype(Y->getIterator()) X##__iterator;\
    decltype(X##__iterator->getItem()) X;\
    auto X##_Func = ([&X##__iterator,&X](decltype(Y) &container)->decltype(true){\
        if(X##__iterator == nullptr){\
            X##__iterator = container->getIterator();\
            if(!X##__iterator->hasValue()) {\
                return false;\
            }\
        }\
        if(X##__iterator->hasValue()) {\
            X = X##__iterator->getItem();\
        }\
        return true;\
    });\
    for(AutoLock X##__forEveryOne_l(X##__m_lock);\
    X##_Func(Y) && X##__iterator->hasValue();\
    X##__iterator->next())

1.获取当前容器的读锁

auto X##__m_lock = __forEveryOneAcquireLock(Y);\

2.获取当前容器的迭代器

decltype(Y->getIterator()) X##__iterator;\

3.定义一个获取容器数据的变量

 decltype(X##__iterator->getItem()) X;\

4.定义一个lambda函数,用来获取当前的容器的数据

auto X##_Func = ([&X##__iterator,&X](decltype(Y) &container)->decltype(true){\
        if(X##__iterator == nullptr){\
            X##__iterator = container->getIterator();\
            if(!X##__iterator->hasValue()) {\
                return false;\
            }\
        }\
        if(X##__iterator->hasValue()) {\
            X = X##__iterator->getItem();\
        }\
        return true;\
    });\

5.记下来就是一个for循环,第一个表达式里面我们初始化了一个AutoLock,这样就能确保遍历concurrentQueue这类的容器时线程安全。如果是遍历ArrayList这类非线程安全的容器,起始这个AutoLock是没有效果的。

for(AutoLock X##__forEveryOne_l(X##__m_lock);\

第二个表达式

 X##_Func(Y) && X##__iterator->hasValue();\

这个主要就是判断是否还有数据,X##_Func(Y)这个是【4】定义的lambda函数,主要做取值的操作。

第三个表达式就很简单了:

X##__iterator->next()

这样就能简单的实现一个自己的foreach函数了~。哈哈。

大家要是感兴趣的话,可以看一下obotcha的github

GitHub - wangsun1983/Obotcha: Tool library writen by C++14

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值