现代双重参考

时间:2016-05-07 00:08:27

标签: c++

我一直在学习一些现代的C ++,改进我的代码风格和东西,然后我到了那个实际上我不理解某些东西的部分。 它基本上都是双重参考:

for (auto&& i = 0; i <= iNumber; ++i){
    std::cout << vecStrings[i] << std::endl; 
}

VS

for (auto i = 0; i <= iNumber; ++i){
    std::cout << vecStrings[i] << std::endl; 
}

这有什么区别?我已经尝试了很多东西,但它并没有真正发挥作用。

1 个答案:

答案 0 :(得分:2)

这种表示法在C ++ 11中是新的,是“移动机制”的一部分。基本思想是我们发现很多情况下C ++必须复制一个对象,作为将它作为参数传递给函数的一部分。在许多情况下,该复制操作涉及内存分配。例如,如果需要复制字符串,则必须创建一个新的内存块以将该文本的副本存储在该字符串中。

我们发现它们经常发生,因此值得改进语言来绕过它们。我们创建了“右值引用”的概念,这是一种以&&结尾的类型。它是“双引用”或“对引用的引用”。它只是一个符号,表示这是一个右值参考。

如果你得到一个rvalue引用,这意味着你的函数的调用者愿意在该rvalue上使用“移动”机制而不是通常的复制机制。使用移动机制,调用者基本上说“在此之后我不打算再使用这个变量,所以如果你想蚕食它并'移出'数据,我不介意。”该规范还为您提供了一个明显的用例:临时变量现在被创建为“右值引用”,这样您就可以窃取它们的内容(它们只会在行尾被取消分配,无论如何)

要使用最常见的示例,复制字符串,std::string(std::string&&)构造函数接受“右值引用”。这个新构造的字符串现在知道调用者不介意我们是否从旧字符串中窃取数据。因此,此构造函数只是将数据指针复制出旧字符串,然后将旧字符串的指针设置为null(或其他具有将数据的所有权从一个字符串“移动”到另一个字符串的效果的东西)。这比为字符串副本分配新空间要有效得多,当我们知道我们将在稍后解除旧的空间时。

在你的情况下,它有点荒谬。从int中删除内容是没有意义的,如果你尝试的话,我认为你不能这样做。这只是一种超级流畅的语法。但是,可能存在重要的情况。例如,您可能正在编写一个将数据从一个向量移动到另一个向量的函数。如果你通过“rvalue reference”传递了向量,你知道调用者不介意你是否可以使用它的数据。如果你使用auto&&来引用该向量中的元素,你现在可以将这些元素传递给另一个函数并告诉它“我不关心你是否蚕食这个元素的内容”,因为你知道你的调用者没有不管怎么说。

在任何一种情况下,语法都允许它。在一些极端情况下这是一个有用的语法(std::move浮现在脑海中)。在大多数情况下,它太过分了。