[英]Why using a reference as an iterator
I was learning about the emplace() of std::vector and stumble upon this code: 我正在学习std :: vector的emplace()并偶然发现以下代码:
// vector::emplace
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector = {10,20,30};
auto it = myvector.emplace ( myvector.begin()+1, 100 );
myvector.emplace ( it, 200 );
myvector.emplace ( myvector.end(), 300 );
std::cout << "myvector contains:";
for (auto& x: myvector)
std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
I am wondering why in the for loop they use a reference auto& x instead of a simple copy, I tried without the & and it worked the same, is this a security to avoid a copy or aa performance trick ? 我想知道为什么在for循环中他们使用引用auto&x而不是简单的副本,而我尝试了不使用&的情况,并且它的工作原理相同,这是避免副本或aa性能技巧的安全性吗?
The other difference between auto
and auto&
in this context is that auto&
will let you modify the value in the vector. auto
和auto&
在这种情况下的另一个区别是auto&
将允许您修改向量中的值。 This may be an undesirable bug just waiting to happen. 这可能是不受欢迎的错误,正等待发生。 Ideally, if you are going to take a reference only for reading, you should take a const reference:
const auto &
理想情况下,如果您打算仅参考阅读,则应使用const参考:
const auto &
The benefit of using the reference when the vector contains objects that are more than a fundamental numeric or pointer type is it won't copy the whole object to a temporary. 当向量包含的对象大于基本数字或指针类型时,使用引用的好处是不会将整个对象复制到临时对象。 If the object has any deep copy semantics, or is perhaps a shared_ptr then there may be significant overhead that is totally avoided.
如果对象具有任何深层复制语义,或者可能是shared_ptr,则可能会存在可避免的大量开销。
For a fundamental type the copy is usually very fast, so a single copy is preferred, but you can expect the compiler optimiser to do the "right thing" if asked to reference a fundamental and then use that reference numerous times, so for template programming you should favour the const-ref over the copy to keep the code simple when you don't know the type. 对于基本类型,该副本通常非常快,因此首选一个副本,但是如果要求您引用一个基本类型然后多次使用该引用,则可以期望编译器优化程序做“正确的事”,因此对于模板编程在不知道类型的情况下,应优先选择const-ref而不是副本,以使代码简单。
It's as simple as you said, it would be a copy. 就像您说的那样简单,它将是一个副本。 So it's indeed a performance trick, but for an
int
it won't be any faster, it might be even be slower. 因此,这的确是一个性能把戏,但对于
int
它不会有任何更快,它可能甚至会更慢。 But had you had a std::vector<std::string>
with million elements then it would make a big difference. 但是如果您有一个带有百万个元素的
std::vector<std::string>
,那么它将大有不同。 You can try it yourself. 您可以自己尝试。
But, it's needed if you want to modify the contents of the iterated container. 但是,如果要修改迭代容器的内容,则需要它。 Without the reference, you would be changing the copy, not the element inside the container.
没有引用,您将更改副本,而不是容器内的元素。 The difference would be seen here:
区别将在这里看到:
std::vector<int> numbers1 = {1,2,3,4};
std::vector<int> numbers2 = {1,2,3,4};
for(auto& x: numbers1) ++x;
for(auto x: numbers2) ++x;
assert(numbers1!=numbers2); // True
Also I would recommend using auto&&
instead of auto&
because it will work better with temporaries, see eg this answer . 另外,我建议使用
auto&&
代替auto&
因为它可以更好地与临时用户配合使用,请参见此答案 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.