C ++ Оператор двойного адреса? (&&)

139

Я читаю исходный код STL и понятия не имею, что &&должен делать адресный оператор. Вот пример кода из stl_vector.h:

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

Имеет ли смысл «Адрес адреса»? Почему у него два оператора адреса вместо одного?

Anarki
источник
3
Может быть, это адрес ссылки.
Гейб
1
@Gabe; это объявление, которое делает ссылку на ссылку, что не имеет никакого смысла, так как сама ссылка не может быть изменена. Адрес может использоваться только в коде, но не при объявлении (параметр, как в этом случае, или как-то иначе). Никогда не видел ничего подобного.
Фальстро
5
Даже если бы был только один &, он не имел бы ничего общего с оператором address-of, но вместо этого означал бы, что __xэто ссылка.
sepp2k
1
Возможный дубликат Что означает T && (двойной амперсанд) в C ++ 11?
Тревор Бойд Смит

Ответы:

112

Это код C ++ 11 . В C ++ 11 &&токен может использоваться для обозначения «ссылки на значение».

aschepler
источник
177

&&Новое в C ++ 11. int&& aозначает, что "a" является ссылкой на r-значение. &&обычно используется только для объявления параметра функции. И это только принимает выражение r-значения. Если вы не знаете, что такое r-значение, простое объяснение состоит в том, что у него нет адреса памяти. Например, число 6 и символ 'v' являются r-значениями. int a, а является l-значением, однако (a+2)является r-значением. Например:

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.
}

Надеюсь, что это информативно.

Лексал Лин
источник
11
Единственный пример, который я хотел бы добавить, это то, как это работает с std :: move. Показываю, что будет с int&& c = std::move( b );т. Д.
Ззач ...
2
Похоже, Sravani S явно плагиат от вас для TutorialsPoint 15 февраля 2018 года здесь .
Габриэль Стейплс
3
Я только что отправил TutorialsPoint это сообщение . Статья, как они плагиат, выглядит следующим образом .
Габриэль Стейплс
87

&&является новым в C ++ 11, и это означает, что функция принимает RValue-Reference, то есть ссылку на аргумент, который должен быть уничтожен.

Билли ОНил
источник
@bronekk: Вы видели дату сообщения в этом сообщении? Он не был опубликован по состоянию на 28 декабря 2010 года.
Билли ONeal
извините за это, сейчас удалено. В следующий раз будем осторожнее :)
bronekk
34

Как уже упоминалось в других ответах, &&токен в этом контексте является новым для C ++ 0x (следующий стандарт C ++) и представляет собой «ссылку на значение».

Rvalue ссылки являются одной из наиболее важных новых вещей в будущем стандарте; они обеспечивают поддержку семантики перемещения в объектах и ​​обеспечивают идеальную пересылку вызовов функций.

Это довольно сложная тема - одним из лучших введений (это не просто краткий обзор ) является статья Стефана Т. Лававея, «Rvalue References: Особенности C ++ 0x в VC10, часть 2»

Обратите внимание, что статья все еще довольно тяжелое чтение, но оно того стоит. И хотя он находится в блоге Microsoft VC ++, вся (или почти вся) информация применима к любому компилятору C ++ 0x.

Майкл Берр
источник
Сам &&токен не нов; его смысл в декларациях есть. Но ты знал это.
aschepler
Это новое в этом контексте. Но для C / C ++ очень традиционно перегружать свои токены, чтобы они имели различное значение в разных контекстах.
Мартин Йорк,
1
@aschkleper - конечно ... логический оператор и даже не приходил мне в голову. Я обновлю ответ.
Майкл Берр
5

Я считаю, что это оператор переезда. 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 - Как создать конструктор перемещения

yash101
источник
1
Какой ваш ответ добавляет к этому 4-летнему вопросу, который еще не был рассмотрен в других ответах?
Человек в маске
5
Я не заметил никакого ответа, как этот, поэтому я решил добавить. Я сталкивался с этим вопросом, прибегая к помощи только сегодня.
yash101