带指针的引用和右引用

时间:2018-02-14 11:33:18

标签: c++ c++11 foreach reference auto

我在C ++设计模式教程中找到了以下代码:

  vector<Object*> objects;
  void foo() override
  {
    cout << "Group contains:\n";
    for (auto&& o : objects)
      o->foo();
  }

在循环中使用右引用的目的是什么?我知道它用于避免临时对象的复制并实现移动语义,但我看不出它在这种情况下是如何应用的,为什么不使用简单的

for (auto o : objects)
  o->foo();

此外,如果使用auto&amp; amp; Ø?所有这些可能性都能正确编译并产生正确的结果......

2 个答案:

答案 0 :(得分:3)

dialogClassName将创建提到的副本,因为它使用值语义来获取对象。您可以使用for (auto o : objects)来避免这种情况。

但是,如果取消引用迭代器(由范围auto& o自动完成)会返回一些代理对象(通常:按值返回),这将不起作用。一个示例可能是std::vector<bool>,它使用such "proxy reference"

然后,这不起作用:

for

因为您无法将rvalue引用绑定到非const左值引用。因此,您可以使用通用引用来解决此问题:

std::vector<bool> vec;
for (auto& v : vec) // fail
{
  ...
}

在您发布的示例中,std::vector<bool> vec; for (auto&& v : vec) // ok { ... } 包含指向对象的指针,因此没有实际区别 - 如果您不想修改内容(因此,不需要通过引用获取指针),使用值是完全正常的,因为复制指针只会导致其值被复制,而不是指针。所以没有真正的收获。使用右值引用也没有任何优势,除非它正确地传播对象vector - 并且如果你改变元素向量存储的类型就更加防弹(它仍然会给你正确的类型,无论是否{{ 1}}返回const / non-const lvalue / rvalue reference)。

更新:实际上,我刚刚发现了类似的问题,几乎与我提供的示例相同。 Link

答案 1 :(得分:2)

  

在循环中使用右引用的目的是什么?

在基于范围的循环中使用auto&&作为通用引用有几个优点:

  • const传播到迭代元素

  • 更好的可维护性:如果您更改了容器所包含的元素,它将做正确的事情。如果您要更改为std::vector<Object>,它仍会获得引用而不是副本(如果您使用的是for(auto o : objects)

有很多关于auto和使用它的地方。我特别喜欢Herb Sutter的this talk,他主张使用它并提供一些很好的指导。