const auto&
如果我想执行只读操作就足够了。 不过,我已经碰到了
for (auto&& e : v) // v is non-const
一对夫妇最近的时间。 这让我怀疑:
是否有可能在一些不起眼的角落情况下,存在使用通用引用一些性能优势,相比于auto&
或const auto&
?
( shared_ptr
是不起眼的角落案件犯罪嫌疑人)
更新两个例子,我在我的收藏中发现:
遍历基本类型时使用const引用的任何缺点?
基于范围的,我可以很容易地遍历使用的地图的值循环?
请专注于一个问题: 我为什么要在使用自动&&范围为基础的for循环?
我能看到的唯一好处是当序列迭代器返回代理引用,你需要在一个非const的方式,参考操作。 例如,考虑:
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto& e : v)
e = true;
}
这并不编译,因为右值vector<bool>::reference
从返回的iterator
将不结合到一个非const左值参考。 但是,这将工作:
#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&& so that I can handle the rvalue reference
// returned for the vector<bool> case
for (auto&& e : v)
e = true;
}
编辑
我这最后一种情况确实应该模板意义。 如果你知道循环总是处理代理基准,然后auto
将工作以及auto&&
。 但是,当环路有时处理非代理的引用,有时代理引用,那么我认为auto&&
会成为首选的解决方案。
使用auto&&
或普遍引用了一系列基于for
-loop的优点是你捕捉你所得到的。 对于大多数类型的迭代器,你可能会得到无论是T&
或T const&
某种类型的T
。 有趣的情况是访问一个迭代器产生一个临时的: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
不同。 为什么要身体一系列基于for
-loop有所不同呢? 当然,实际利用已经推导出使用你需要把它们相应的普遍引用的类型:
for (auto&& x: range) {
f(std::forward<decltype(x)>(x));
}
当然,使用std::forward()
意味着你接受从任何移动的返回值。 不管这样的对象,使非模板代码多大意义,我不知道(没有?)。 我可以想像,使用通用引用可以提供更多的信息,编译器做正确的事。 在模板代码它保持了制作上应与对象发生的事情作出任何决定。
我实际上总是使用auto&&
。 为什么要由一个边缘的情况下得到咬伤,当你不就得了? 这是更短的输入过了,我只是觉得它更...透明。 当您使用auto&& x
,那么你知道, x
正是*it
,每一次。
文章来源: What is the advantage of using universal references in range-based for loops?