Ali*_*Ali 111 c++ performance for-loop move-semantics c++11
const auto&如果我想执行只读操作就足够了.但是,我已经碰到了
for (auto&& e : v) // v is non-const
Run Code Online (Sandbox Code Playgroud)
最近几次.这让我想知道:
是否有可能在一些不起眼的角落情况下,存在使用通用引用一些性能优势,相比auto&还是const auto&?
(shared_ptr是一个晦涩角落案件的嫌疑人)
更新 我在收藏夹中找到的两个示例:
迭代基本类型时使用const引用的任何缺点?
我可以使用基于范围的for循环轻松迭代地图的值吗?
请专注于一个问题:我为什么要在使用自动&&范围为基础的for循环?
How*_*ant 87
我能看到的唯一优势是当序列迭代器返回一个代理引用时,你需要以非const方式对该引用进行操作.例如考虑:
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto& e : v)
e = true;
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,因为vector<bool>::reference从iterator将返回的rvalue 不会绑定到非const左值引用.但这会奏效:
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto&& e : v)
e = true;
}
Run Code Online (Sandbox Code Playgroud)
所有这一切,除非你知道你需要满足这样一个用例,否则我不会这样编码.即我不会无偿地这样做,因为它确实让人们想知道你在做什么.如果我这样做了,那么为什么包括评论也不会有什么坏处:
#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;
}
Run Code Online (Sandbox Code Playgroud)
编辑
我的最后一个案例应该是一个有意义的模板.如果你知道循环总是处理代理引用,那么auto就可以了auto&&.但是当循环有时处理非代理引用和有时代理引用时,我认为auto&&它将成为首选的解决方案.
Die*_*ühl 25
使用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;
}
Run Code Online (Sandbox Code Playgroud)
该函数对象f可以治疗T&,T const&以及T不同.为什么基于范围的for循环体不同?当然,要实际利用使用通用引用推断出类型,您需要相应地传递它们:
for (auto&& x: range) {
f(std::forward<decltype(x)>(x));
}
Run Code Online (Sandbox Code Playgroud)
当然,使用std::forward()意味着您接受要移动的任何返回值.这样的对象在非模板代码中是否有用,我不知道(还是?).我可以想象使用通用引用可以为编译器提供更多信息来做正确的事情.在模板化代码中,它不会对对象应该发生什么做出任何决定.
我几乎总是使用auto&&.当你不需要时,为什么会被边缘情况所困扰?键入也更短,我发现它更透明.当你使用时auto&& x,你就知道每次x都是这样*it.
| 归档时间: |
|
| 查看次数: |
19761 次 |
| 最近记录: |