为什么使用引用作为迭代器
Why using a reference as an iterator
我正在学习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;
}
我想知道为什么在 for 循环中使用引用 auto&x 而不是简单的副本,我尝试没有 &并且它的工作原理相同,这是避免复制的安全性还是性能技巧?
在此上下文中,auto
和 auto&
之间的另一个区别是auto&
允许您修改向量中的值。这可能是一个等待发生的不良错误。理想情况下,如果您打算仅将参考文献用于阅读,则应使用常量参考:const auto &
当矢量包含的对象超过基本数字或指针类型时,使用引用的好处是它不会将整个对象复制到临时对象。如果对象具有任何深层复制语义,或者可能是shared_ptr则可能会完全避免大量开销。
对于基本类型,复制通常非常快,因此首选单个副本,但是如果要求编译器引用基本类型,然后多次使用该引用,您可以期望编译器优化器执行"正确的操作",因此对于模板编程,您应该优先使用 const-ref 而不是副本,以便在您不知道类型时保持代码简单。
就像你说的那么简单,它会是一个副本。所以这确实是一个性能技巧,但对于int
来说,它不会更快,甚至可能更慢。但是如果你有一个有百万元素的std::vector<std::string>
,那么它会有很大的不同。您可以自己尝试。
但是,如果要修改迭代容器的内容,则需要它。如果没有引用,您将更改副本,而不是容器内的元素。区别将在这里看到:
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
此外,我建议使用auto&&
而不是auto&
,因为它可以更好地与临时人员一起使用,请参阅例如此答案。
相关文章:
- 不明白迭代器,引用和指针失效,一个例子
- boost_multi_index迭代器取消引用给出常量
- 为什么"std::uninitialized_copy"通常取消对未初始化内存的迭代器的引用不是未定
- 矢量迭代器不能与 std::shared_ptr<> 取消引用
- 无法取消引用值初始化迭代器
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- C++不能取消引用结束列表迭代器
- 如何取消引用向量迭代器
- 在此C++代码中,迭代器引用列表的哪个元素?
- 使用双迭代器引用映射中的列表
- 使用自动迭代器引用对象
- 另一个迭代器引用的对象被另一个迭代器删除
- C++ 使用迭代器引用连续值
- 正确取消对指针的迭代器引用
- 如何在C++中存储对 stl 容器元素的指针/迭代器引用
- 具有代理迭代器/引用和auto的容器
- 返回迭代器引用C++
- 迭代器引用 std::vector<std::unique_ptr<T>>
- 迭代器引用受控序列中的元素的要求
- 什么是自动迭代器引用的 C++98 等效项?