在基于范围for循环中使用通用引用的优点是什么?

如果我想执行只读操作, const auto&就足够了。 但是,我碰到了

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

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

是否有可能在一些不起眼的angular落案例中使用通用引用有一些性能优势,与auto& or const auto&相比?

shared_ptr是一个晦涩的angular落案件的嫌疑犯)


更新我在我的collections中find的两个例子:

迭代基本types时使用const引用的任何缺点?
我可以使用基于范围的for循环轻松地迭代地图的值吗?

请专注于这个问题: 为什么我要在基于范围的for循环中使用auto &&?

我能看到的唯一优点是序列迭代器返回代理引用时,您需要以非const方式对该引用进行操作。 例如考虑:

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

这不会编译,因为从iterator返回的右值vector<bool>::reference不会绑定到非常量左值引用。 但是这将工作:

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

尽pipe如此,除非您知道您需要满足这样的用例,否则我不会这样编写代码。 也就是说,我不会这样做,因为它确实会引起人们想知道你在做什么。 如果我确实这么做了,那么为什么要包括一个评论呢?

 #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; } 

编辑

我最后一个例子应该是一个有意义的模板。 如果你知道循环总是处理一个代理引用,那么autoauto&& 。 但是,当循环有时处理非代理引用,有时代理引用,那么我认为auto&&将成为select的解决scheme。

使用auto&&或通用引用与基于范围的-loop相比,您可以捕获所获取的内容。 对于大多数types的迭代器,你可能会得到一个T&T const&对于某些Ttypes。 有趣的例子是解引用一个迭代器产生一个临时的:C ++ 2011得到了宽松的需求,迭代器不一定需要产生一个左值。 通用引用的使用匹配std::for_each()中的参数转发:

 template <typename InIt, typename F> F std::for_each(InIt it, InIt end, F f) { for (; it != end; ++it) { f(*it); // <---------------------- here } return f; } 

函数对象f可以不同地处理T&T const&T 为什么一个基于范围的循环的主体是不同的呢? 当然,要真正利用通用引用推导出types,您需要相应地传递它们:

 for (auto&& x: range) { f(std::forward<decltype(x)>(x)); } 

当然,使用std::forward()意味着你接受任何从中移出的返回值。 这样的对象在非模板代码中是否有意义,我不知道(还没有?)。 我可以想象,使用通用引用可以为编译器提供更多的信息来做正确的事情。 在模板化的代码中,它没有做出关于对象应该发生什么的决定。

我几乎总是使用auto&& 。 为什么当你不必要的时候被一个边缘案例咬住? 键入的时间也更短,我只是觉得它更透明。 当你使用auto&& x ,那么你就知道x都是x