当前位置: 首页 > 知识库问答 >
问题:

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

鲁钱明
2023-03-14

const自动

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

最近有几次。这让我不禁好奇:

auto相比,在一些模糊的情况下,使用转发引用是否可能有一些性能优势

shared_ptr是不明角落案件的嫌疑人)

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

在迭代基本类型时使用const引用有什么缺点吗
我可以使用基于范围的for循环轻松迭代贴图的值吗?

请把注意力集中在这个问题上:我为什么要使用汽车


共有3个答案

白念
2023-03-14

我几乎总是使用auto

上官鸿祯
2023-03-14

使用auto

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

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

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

仲孙经赋
2023-03-14

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

#include <vector>

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

这不会编译,因为rvaluevector

#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一样工作

 类似资料:
  • 由于valgrind中出现了一些分段错误和警告,我发现这段代码不正确,并且在for range循环中有一些悬而未决的引用。 看起来好像开始和结束是从一个临时循环中提取的,并且在循环中丢失了。 当然,一种方法是 然而,我想知道为什么for(auto e:f()[5])是一个错误,以及是否有更好的方法或某种方法来设计f,甚至容器(

  • 在临时范围上基于范围的for循环中,Barry提到以下内容不受被破坏的临时对象的影响,我测试的成员v确实存在于for循环的整个循环中(因为在for循环的整个循环中没有调用析构函数X)。解释是什么?

  • 我在实验基于范围的for循环时发现,如果你使用基于范围的for循环来循环一个向量,它会出现超出范围的错误,如果你使用基于范围的for循环,有没有办法避免这个错误 它会显示此错误

  • 对于我的项目,我需要使循环中的迭代器转到容器中的下一项,执行一些操作,然后再次返回到同一迭代器,然后继续,然而,由于某种原因,和,然后使用似乎都不起作用。那么,我怎样才能得到下一个迭代器,然后返回到上一个迭代器呢? 我收到以下错误消息: 非常感谢。

  • C 11 使用基于范围的for循环对作为类成员的std::向量进行迭代的代码是什么?我尝试了以下几个版本:

  • 考虑基于范围的for循环的begin expr和end expr的规范(N4140[标准范围]/p1)。给定类型为RangeT的范围, 开始表达式和结束表达式的确定如下: 如果“范围”是数组类型,则“开始表达式”和“结束表达式”分别是“范围”和“范围绑定”,其中“范围绑定”是数组绑定。如果RangeT是大小未知的数组或类型不完整的数组,则程序格式错误 如果RangeT是类类型,则在类RangeT的