C++双地址运算符是什么?(&&)

229

我正在阅读STL源代码,但不知道&&地址运算符应该做什么。这里是来自stl_vector.h的一个代码示例:

vector&
operator=(vector&& __x) // <-- Note double ampersands here
{
    // NB: DR 675.
    this->clear();
    this->swap(__x); 
    return *this;
}

“地址的地址”有意义吗?为什么它需要两个地址运算符而不是一个?


4
或许这是一个参考文献的地址。 - Gabe
2
@Gabe;这是一个声明,因此它将成为对引用的引用,这没有任何意义,因为引用本身无法被修改。取地址符号只能在代码中使用,而不能在声明时使用(例如在此情况下作为参数或其他方式)。虽然我从未见过类似的情况。 - falstro
6
即使只有一个&,它也与取地址运算符无关,而是表示__x是一个引用。 - sepp2k
3
可能是 What does T&& (double ampersand) mean in C++11? 的重复问题。 - Trevor Boyd Smith
重复的应该是最后一个,这个问题在4个月前就被问过了。 - Ictus
6个回答

333

&&是C++11新增的特性。 int&& a表示"a"是一个右值引用。 &&通常只用于声明函数的参数,并且它仅仅接受一个右值表达式。如果您不知道右值是什么,简单来说就是它没有内存地址。例如数字6和字符'v'都是右值。int a中,a是左值,但是(a+2)是右值。例如:

void foo(int&& a)
{
    //Some magical code...
}

int main()
{
    int b;
    foo(b); //Error. An rValue reference cannot be pointed to a lValue.
    foo(5); //Compiles with no error.
    foo(b+3); //Compiles with no error.

    int&& c = b; //Error. An rValue reference cannot be pointed to a lValue.
    int&& d = 5; //Compiles with no error.
}

希望这很有信息量。


25
我希望你能增加一个例子,展示如何使用std::move。 比如 int&& c = std::move( b ); 的情况下会发生什么。 - AlwaysTalkingAboutMyDog
31
据看起来,Sravani S在2018年2月15日的TutorialsPoint网站上毫不掩饰地抄袭了你的内容,链接在这里:https://www.tutorialspoint.com/What-is-double-address-operator-and-and-in-Cplusplus。 - Gabriel Staples
19
我刚刚向TutorialsPoint发送了此信息。他们剽窃的文章 看起来像这样 - Gabriel Staples
2
还有另一个重载函数 void push_back (const value_type& val); 接受左值。 - Lexseal Lin
9
2022年了,TutorialsPoint仍然展示着抄袭的内容。 - Ricardo Cárdenes
显示剩余3条评论

138

这是关于 C++11 的代码。在 C++11 中,&& 这个标记可以用来表示 "右值引用"。


1
真的吗?这个解释很好!X代表Y。但是Y到底是什么意思?哎呀!没有解释! - undefined

111

&& 是 C++11 中的新特性,表示该函数接受一个 右值引用 -- 即对将要被销毁的参数的引用。


42

正如其他答案所提到的,在这个上下文中,&&符号是C++0x(下一个C++标准)中新增的一个表示“右值引用”的符号。

右值引用是即将发布的标准中比较重要的新特性之一;它们使得对象支持“移动”语义,并允许完美转发函数调用。

这是一个相当复杂的主题——其中一个最好的入门文章(不仅仅是概述)是由Stephan T. Lavavej撰写的一篇文章,"Rvalue References: C++0x Features in VC10, Part 2"

请注意,这篇文章还是相当深度的阅读材料,但非常值得阅读。虽然它是在Microsoft VC++博客上发布的,但所有(或几乎所有)信息都适用于任何C++0x编译器。


&& 符号本身并不是新的;它在声明中的含义是新的。但你已经知道了。 - aschepler
这在这个上下文中是新的。但是在C/C++中,重载其标记以在不同的上下文中具有不同的含义是非常传统的。 - Martin York
1
@aschkleper - 当然... 逻辑与运算符甚至没有进入我的脑海。我会更新答案。 - Michael Burr
链接失效了...所以答案毫无意义。 - Jiminion
3
http://thbecker.net/articles/rvalue_references/section_01.html - Jiminion

6
我认为这是一个移动操作符。 operator= 是赋值操作符,例如vector x = vector y。调用clear()函数听起来像是删除向量中的内容以防止内存泄漏。该操作符返回指向新向量的指针。

这样,

std::vector<int> a(100, 10);
std::vector<int> b = a;
for(unsigned int i = 0; i < b.size(); i++)
{
    std::cout << b[i] << ' ';
}

尽管我们给向量a赋了值,但向量b具有这些值。这就是 "operator=()" 的魔力所在! MSDN -- 如何创建移动构造函数

1
你的回答对这个四年前的问题有什么补充,而其他回答中没有涉及到的内容呢? - Masked Man
7
我没有看到像这样的答案,所以决定补充一下。今天刚好通过谷歌找到了这个问题。 - yash101

3

我相信 && 是用于移动语义的。它允许某个对象将其内存释放给其他需要它的对象,避免了复制的必要。

移动构造函数 例如:

String(String&& other) noexcept
{
//...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接