c++ 您所在的位置:网站首页 双∑符号什么意思 c++

c++

2024-05-20 23:09| 来源: 网络整理| 查看: 265

我一直在研究 C++11 的一些新特性,我注意到一个是声明变量时的双 & 号,比如 T&& var .

首先,这个野兽叫什么?我希望谷歌允许我们搜索这样的标点符号。

究竟是什么意思?

乍一看,它似乎是一个双重引用(如 C 风格的双指针 T** var),但我很难想到它的用例。

最佳答案

它声明了一个 rvalue reference (标准提案文档)。这里是rvalue的介绍references .这是微软标准库之一对右值引用的精彩深入研究developers .

CAUTION: the linked article on MSDN ("Rvalue References: C++0x Features in VC10, Part 2") is a very clear introduction to Rvalue references, but makes statements about Rvalue references that were once true in the draft C++11 standard, but are not true for the final one! Specifically, it says at various points that rvalue references can bind to lvalues, which was once true, but was changed.(e.g. int x; int &&rrx = x; no longer compiles in GCC) – drewbarbs Jul 13 '14 at 16:12

C++03 引用(现在在 C++11 中称为左值引用)之间的最大区别在于它可以像临时对象一样绑定(bind)到右值,而不必是 const。因此,这种语法现在是合法的:T&& r = T(); 右值引用主要提供以下内容: 移动语义 .现在可以定义移动构造函数和移动赋值运算符,它们采用右值引用而不是通常的 const-lvalue 引用。移动的功能与拷贝类似,只是它不必保持源不变;事实上,它通常会修改源,使其不再拥有移动的资源。这对于消除无关拷贝非常有用,尤其是在标准库实现中。例如,复制构造函数可能如下所示:foo(foo const& other) { this->length = other.length; this->ptr = new int[other.length]; copy(other.ptr, other.ptr + other.length, this->ptr); } 如果此构造函数传递了一个临时对象,则拷贝将是不必要的,因为我们知道临时对象将被销毁;为什么不利用已经分配的临时资源呢?在 C++03 中,没有办法阻止复制,因为我们无法确定我们是否被传递了一个临时的。在 C++11 中,我们可以重载移动构造函数:foo(foo&& other) { this->length = other.length; this->ptr = other.ptr; other.length = 0; other.ptr = nullptr; } 注意这里的巨大差异:移动构造函数实际上修改了它的参数。这将有效地将临时对象“移动”到正在构造的对象中,从而消除不必要的拷贝。移动构造函数将用于临时变量和使用 std::move 显式转换为右值引用的非常量左值引用。函数(它只是执行转换)。以下代码均调用 f1 的移动构造函数和 f2 :foo f1((foo())); // Move a temporary into f1; temporary becomes "empty" foo f2 = std::move(f1); // Move f1 into f2; f1 is now "empty" 完美转发 .右值引用允许我们正确地转发模板化函数的参数。以这个工厂函数为例:template std::unique_ptr factory(A1& a1) { return std::unique_ptr(new T(a1)); } 如果我们拨打 factory(5) ,该参数将被推导出为 int& ,它不会绑定(bind)到文字 5,即使 foo的构造函数采用 int .好吧,我们可以改用 A1 const& ,但如果 foo通过非常量引用接受构造函数参数?要创建一个真正通用的工厂函数,我们必须在 A1& 上重载工厂函数。并在 A1 const& .如果工厂采用 1 个参数类型,那可能没问题,但是每个额外的参数类型都会将必要的重载集乘以 2。这很快就无法维护。右值引用通过允许标准库定义一个 std::forward 来解决这个问题。可以正确转发左值/右值引用的函数。更多关于如何std::forward的信息作品,见 this excellent answer .这使我们能够像这样定义工厂函数:template std::unique_ptr factory(A1&& a1) { return std::unique_ptr(new T(std::forward(a1))); } 现在参数的右值/左值在传递给 T 时被保留。的构造函数。这意味着如果用右值调用工厂,T的构造函数使用右值调用。如果用左值调用工厂,T的构造函数使用左值调用。改进后的工厂函数由于一条特殊规则而起作用:

When the function parameter type is of the form T&& where T is a template parameter, and the function argument is an lvalue of type A, the type A& is used for template argument deduction.

因此,我们可以像这样使用工厂:auto p1 = factory(foo()); // calls foo(foo&&) auto p2 = factory(*p1); // calls foo(foo const&) 重要的右值引用属性 :对于过载解决方案,左值更喜欢绑定(bind)到左值引用,而右值更喜欢绑定(bind)到右值引用 .因此,为什么临时对象更喜欢调用移动构造函数/移动赋值运算符而不是复制构造函数/赋值运算符。 右值引用将隐式绑定(bind)到右值和作为隐式转换结果的临时变量 .即 float f = 0f; int&& i = f;格式良好,因为 float 可以隐式转换为 int;引用将是一个临时的,它是转换的结果。 命名的右值引用是左值。未命名的右值引用是右值。 这对于理解 std::move 的原因很重要。需要调用:foo&& r = foo(); foo f = std::move(r);

关于c++ - T&&(双与号)在 C++11 中是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5481539/



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有