在基于范围的循环中使用通用引用的优点是什么? [英] What is the advantage of using universal references in range-based for loops?

查看:169
本文介绍了在基于范围的循环中使用通用引用的优点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想执行只读操作,则

const auto& 就足够了。但是,我碰到了

  for(auto& e:v)// v is non-const 

最近几次。这使我想知道:



在某些模糊的角落情况下,使用通用引用可能会有一些性能优势,相比之下 auto& / code>或 const auto&



shared_ptr 是可疑的不明角色情况)






更新
我在我的收藏夹中找到的两个示例:



使用const引用的任何缺点何时迭代基本类型?

我可以轻松地迭代地图的值,使用基于范围的for循环?



请集中于以下问题:为什么要使用auto&基于范围的for循环?

解决方案

我可以看到的唯一优势是当序列迭代器返回一个代理引用,并且您需要以非常量方式对该引用进行操作。例如考虑:

  #include< vector> 

int main()
{
std :: vector< bool> v(10);
for(auto& e:v)
e = true;
}

这不会编译,因为rvalue vector< bool> ;从迭代器返回的参考不会绑定到非常量的值。但这将工作:

  #include< vector> 

int main()
{
std :: vector< bool> v(10);
for(auto& e:v)
e = true;
}

所有这些,我不会这样编码,除非你知道你需要满足这样的用例。也就是说我不会这样做,因为它 使人们想知道你在做什么。如果我这样做了,为什么不包括一个注释不会伤害:

  #include< vector> 

int main()
{
std :: vector< bool> v(10);
// using auto&&&所以我可以处理向量< bool>返回的右值引用
//。 case
for(auto& e:v)
e = true;
}

编辑

我的最后一个案例应该是一个有意义的模板。如果你知道循环总是处理一个代理引用,那么 auto 将工作,以及 auto&& 。但是当循环有时处理非代理引用和有时代理引用时,我认为 auto&&& 将成为选择的解决方案。


const auto& would suffice if I want to perform read-only operations. However, I have bumped into

for (auto&& e : v)  // v is non-const

a couple of times recently. This makes me wonder:

Is it possible that in some obscure corner cases there is some performance benefit in using universal references, compared to auto& or const auto&?

(shared_ptr is a suspect for obscure corner cases)


Update Two examples that I found in my favorites:

Any disadvantage of using const reference when iterating over basic types?
Can I easily iterate over the values of a map using a range-based for loop?

Please concentrate on the question: why would I want to use auto&& in range-based for loops?

解决方案

The only advantage I can see is when the sequence iterator returns a proxy reference and you need to operate on that reference in a non-const way. For example consider:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto& e : v)
        e = true;
}

This doesn't compile because rvalue vector<bool>::reference returned from the iterator won't bind to a non-const lvalue reference. But this will work:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto&& e : v)
        e = true;
}

All that being said, I wouldn't code this way unless you knew you needed to satisfy such a use case. I.e. I wouldn't do this gratuitously because it does cause people to wonder what you're up to. And if I did do it, it wouldn't hurt to include a comment as to why:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    // using auto&& so that I can handle the rvalue reference
    //   returned for the vector<bool> case
    for (auto&& e : v)
        e = true;
}

Edit

This last case of mine should really be a template to make sense. If you know the loop is always handling a proxy reference, then auto would work as well as auto&&. But when the loop was sometimes handling non-proxy references and sometimes proxy-references, then I think auto&& would become the solution of choice.

这篇关于在基于范围的循环中使用通用引用的优点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆