C++11 基于范围的 for 循环效率“const auto &i”与“auto i”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17032267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++11 Range-based for-loop efficiency "const auto &i" versus "auto i"
提问by user2052561
In C++11, I can iterate over some container like so:
在 C++11 中,我可以像这样迭代某个容器:
for(auto i : vec){
std::cout << i << std::endl;
}
But I know that this needlessly - needlessly, since I only need to printthe values of vec
- makes a copy of (EDIT: each element of) vec
, so instead I could do:
但我知道这是不必要的 -不必要的,因为我只需要打印的值vec
- 复制(编辑:每个元素)vec
,所以我可以这样做:
for(auto &i : vec){
std::cout << i << std::endl;
}
But I want to make sure that the values of vec
are never modified and abide by const-correctness, so I can do:
但我想确保vec
永远不会修改的值并遵守常量正确性,所以我可以这样做:
for(const auto &i : vec){
std::cout << i << std::endl;
}
So my question is: If I only need to lookat the values of some container, wouldn't the very last loop (const auto &i
) always be preferred due to the increased effieciency of not having an extra copy of (EDIT: each element of) vec
?
所以我的问题是:如果我只需要查看某个容器的值,那么最后一个循环 ( const auto &i
) 是否总是首选,因为没有额外副本 ( EDIT: each element of) 的效率提高vec
?
I have a program that I'm developing in which I'm considering making this change throughout, since efficiency is critical in it (the reason I'm using C++ in the fist place).
我有一个正在开发的程序,我正在考虑在其中进行此更改,因为效率在其中至关重要(这是我首先使用 C++ 的原因)。
回答by GManNickG
Yes. The same reason if you only ever read an argument you make the parameter const&
.
是的。同样的原因,如果你只读过一个参数,你就创建了参数const&
。
T // I'm copying this
T& // I'm modifying this
const T& // I'm reading this
Those are your "defaults". When T
is a fundamental type (built-in), though, you generally just revert to const T
(no reference) for reading, because a copy is cheaper than aliasing.
这些是你的“默认值”。但是,whenT
是基本类型(内置),您通常只需恢复到const T
(无引用)进行读取,因为副本比别名更便宜。
I have a program that I'm developing in which I'm considering making this change throughout, since efficiency is critical in it
我正在开发一个程序,我正在考虑在其中进行此更改,因为效率在其中至关重要
- Don't make blind sweeping changes. A working program is better than a fast but broken program.
- How you iterate through your loops probably won't make much of a difference; you're looping for a reason, aren't you? The body of your loop will much more likely be the culprit.
- If efficiency is critical, you want to use a profilerto find which parts of your program are actuallyslow, rather than guess at parts that mightbe slow. See #2 for why your guess may be wrong.
- 不要盲目地进行彻底的改变。一个有效的程序比一个快速但损坏的程序要好。
- 你如何迭代你的循环可能不会有太大的不同;你循环是有原因的,不是吗?循环体更有可能是罪魁祸首。
- 如果效率很重要,您希望使用分析器来查找程序的哪些部分实际上很慢,而不是猜测可能很慢的部分。请参阅 #2 了解为什么您的猜测可能是错误的。
回答by idclev 463035818
Disclaimer: In general the difference between auto
and auto&
is subtle, partly a matter of style, but sometimes also a matter of correctness. I am not going to cover the general case here!
免责声明:一般来说,auto
和之间的区别auto&
是微妙的,部分是风格问题,但有时也是正确性问题。我不会在这里介绍一般情况!
In a range based for loop, the difference between
在基于范围的 for 循环中,
for (auto element : container) {}
and
和
for (auto& element_ref : container) {}
is that element
is a copy of the elements in the container
, while element_ref
is a reference to the elements in the container.
是 中element
元素的副本container
,而element_ref
是对容器中元素的引用。
To see the difference in action, consider this example:
要查看操作上的差异,请考虑以下示例:
#include <iostream>
int main(void) {
int a[5] = { 23,443,16,49,66 };
for (auto i : a) i = 5;
for (const auto& i : a) std::cout << i << std::endl;
for (auto& i : a) i = 5;
for (const auto& i : a) std::cout << i << std::endl;
}
It will print
它会打印
23
443
16
49
66
5
5
5
5
5
because the first loop works on copies of the array elements, while the second actually modifies the elements in the array.
因为第一个循环处理数组元素的副本,而第二个循环实际上修改数组中的元素。
If you dont want to modify the elements then often a const auto&
is more appropriate, because it avoids copying the elements (which can be expensive).
如果您不想修改元素,那么通常 aconst auto&
更合适,因为它避免了复制元素(这可能很昂贵)。
回答by Visiedo
Imagine if your vector contains strings. Long strings. 5000 long strings. Copy them unnecessarily and you end up with a nicely written for loop that is awfully inefficient.
想象一下,如果您的向量包含字符串。长字符串。5000 长字符串。不必要地复制它们,你最终会得到一个非常低效的写得很好的 for 循环。
Make sure your code follows your intention. If you do not need a copy inside of the loop, do not make one.
确保您的代码遵循您的意图。如果您不需要循环内的副本,请不要制作副本。
Use a reference & as suggested above, or iterators.
使用上面建议的引用 & 或迭代器。