什么是使用普遍引用的优势范围为基础的循环?(What is the advantage of usi

2019-06-18 16:43发布

const auto&如果我想执行只读操作就足够了。 不过,我已经碰到了

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

一对夫妇最近的时间。 这让我怀疑:

是否有可能在一些不起眼的角落情况下,存在使用通用引用一些性能优势,相比于auto&const auto&

shared_ptr是不起眼的角落案件犯罪嫌疑人)


更新两个例子,我在我的收藏中发现:

遍历基本类型时使用const引用的任何缺点?
基于范围的,我可以很容易地遍历使用的地图的值循环?

请专注于一个问题: 我为什么要在使用自动&&范围为基础的for循环?

Answer 1:

我能看到的唯一好处是当序列迭代器返回代理引用,你需要在一个非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&&会成为首选的解决方案。



Answer 2:

使用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()意味着你接受从任何移动的返回值。 不管这样的对象,使非模板代码多大意义,我不知道(没有?)。 我可以想像,使用通用引用可以提供更多的信息,编译器做正确的事。 在模板代码它保持了制作上应与对象发生的事情作出任何决定。



Answer 3:

我实际上总是使用auto&& 。 为什么要由一个边缘的情况下得到咬伤,当你不就得了? 这是更短的输入过了,我只是觉得它更...透明。 当您使用auto&& x ,那么你知道, x正是*it ,每一次。



文章来源: What is the advantage of using universal references in range-based for loops?