在C ++ 11中,我可以像这样迭代一些容器:
for(auto i : vec){
std::cout << i << std::endl;
}
但我知道这不必要 - 不必要,因为我只需要打印 vec
的值 - 制作副本(编辑:vec
的每个元素,所以我可以这样做:
for(auto &i : vec){
std::cout << i << std::endl;
}
但我想确保vec
的值永远不会被修改并遵守const-correctness,所以我可以这样做:
for(const auto &i : vec){
std::cout << i << std::endl;
}
所以我的问题是:如果我只需要查看某个容器的值,那么由于效率的提高,最后一个循环(const auto &i
)不会总是首选没有额外的副本(编辑:每个元素)vec
?
我正在开发一个我正在开发的程序,我正考虑在整个过程中进行此项更改,因为效率至关重要(我之所以在第一时间使用C ++)。
答案 0 :(得分:65)
是。如果您只读取参数const&
。
T // I'm copying this
T& // I'm modifying this
const T& // I'm reading this
这些是你的“默认值”。但是,当T
是基本类型(内置)时,您通常只需要恢复为const T
(无引用)进行读取,因为副本比别名更便宜。
我正在开发一个我正在开发的程序,我正考虑在整个过程中进行此更改,因为效率至关重要
答案 1 :(得分:1)
免责声明:auto
和auto&
之间的区别通常是微妙的,部分取决于样式,但有时也取决于正确性。我不会在这里介绍一般情况!
在基于循环的范围内,两者之间的区别
for (auto element : container) {}
和
for (auto& element_ref : container) {}
是element
是container
中元素的副本,而element_ref
是对容器中元素的引用。
要查看实际效果,请考虑以下示例:
#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;
}
它将打印
23
443
16
49
66
5
5
5
5
5
因为第一个循环处理数组元素的副本,而第二个循环实际上修改了数组中的元素。
如果您不想修改元素,那么通常使用const auto&
更合适,因为它避免了复制元素(这可能会很昂贵)。
答案 2 :(得分:0)
想象一下,如果你的矢量包含字符串。长串。 5000长串。不必要地复制它们,你最终会得到一个非常低效的for循环。
确保您的代码符合您的意图。如果您不需要在循环内部复制,请不要制作副本。
使用参考&amp;如上所述,或迭代器。