Operator podwójnego adresu w C ++? (&&)

137

Czytam kod źródłowy STL i nie mam pojęcia, co &&ma zrobić operator adresu. Oto przykład kodu z stl_vector.h:

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

Czy „Adres adresu” ma sens? Dlaczego ma dwa operatory adresu zamiast tylko jednego?

Anarki
źródło
2
Może to adres odniesienia.
Gabe
1
@Gabe; jest to deklaracja, która uczyniłaby z niej odniesienie do odniesienia, co nie ma żadnego sensu, ponieważ samo odniesienie nie może być modyfikowane. Adres-of może być używany tylko w kodzie, a nie podczas deklarowania (parametr jak w tym przypadku lub w innym przypadku). Nigdy jednak czegoś takiego nie widziałem.
falstro
5
Nawet gdyby istniał tylko jeden &, nie miałby nic wspólnego z operatorem address-of, ale zamiast tego oznaczałby, że __xjest to odniesienie.
sepp2k
1
Możliwy duplikat Co oznacza T && (podwójny ampersand) w C ++ 11?
Trevor Boyd Smith

Odpowiedzi:

112

To jest kod w C ++ 11 . W C ++ 11 &&token może oznaczać „odwołanie do wartości r”.

aschepler
źródło
174

&&jest nowy w C ++ 11. int&& aoznacza, że ​​„a” jest odniesieniem do wartości r. &&jest zwykle używany tylko do deklarowania parametru funkcji. I wymaga tylko wyrażenia wartości r. Jeśli nie wiesz, czym jest wartość r, prostym wyjaśnieniem jest to, że nie ma ona adresu pamięci. Np. Liczba 6 i znak „v” są wartościami r. int a, a jest wartością l, jednak (a+2)jest wartością r. Na przykład:

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

Mam nadzieję, że to pouczające.

Lexseal Lin
źródło
11
Jedyny przykład, który chciałbym dodać, to jak to działa ze std :: move. Pokazywanie, co by się stało int&& c = std::move( b );, itp.
Zzzach ...
2
Wygląda na to, że Sravani S rażąco plagiatował od Ciebie TutorialsPoint 15 lutego 2018 r., Tutaj .
Gabriel Staples
3
Właśnie wysłałem TutorialsPoint tę wiadomość . Artykuł, jako plagiat przez nich, wygląda następująco .
Gabriel Staples
86

&&jest nowością w C ++ 11 i oznacza, że ​​funkcja akceptuje odwołanie do RValue - to znaczy odwołanie do argumentu, który ma zostać zniszczony.

Billy ONeal
źródło
@bronekk: Czy widziałeś datę publikacji tej wiadomości? Nie został opublikowany 28 grudnia 2010.
Billy ONeal
przepraszam za to, usunięte teraz. Następnym razem będzie ostrożniej :)
bronekk
34

Jak wspomniały inne odpowiedzi, &&token w tym kontekście jest nowy w C ++ 0x (następny standard C ++) i reprezentuje „odwołanie do wartości r”.

Odniesienia do wartości R są jedną z ważniejszych nowości w nadchodzącym standardzie; umożliwiają obsługę semantyki „przenoszenia” na obiektach i pozwalają na doskonałe przekazywanie wywołań funkcji.

To dość złożony temat - jednym z najlepszych wstępów (to nie tylko pobieżne) jest artykuł Stephana T. Lavaveja „Rvalue References: C ++ 0x Features in VC10, Part 2”

Zwróć uwagę, że artykuł jest nadal dość ciężki, ale warto go przeczytać. I chociaż znajduje się na blogu Microsoft VC ++, wszystkie (lub prawie wszystkie) informacje mają zastosowanie do dowolnego kompilatora C ++ 0x.

Michael Burr
źródło
Sam &&token nie jest nowy; jego znaczenie w deklaracjach jest. Ale wiedziałeś o tym.
aschepler
W tym kontekście to nowość. Jednak w C / C ++ bardzo tradycyjne jest przeciążanie swoich tokenów, aby mieć różne znaczenie w różnych kontekstach.
Martin York
1
@aschkleper - oczywiście ... logika - i operator nawet nie przyszedł mi do głowy. Zaktualizuję odpowiedź.
Michael Burr
5

Uważam, że jest to operator ruchu. operator=jest, powiedzmy, operatorem przypisania vector x = vector y. clear()Wywołanie funkcji brzmi tak, jakby usuwa zawartość wektora aby zapobiec wycieku pamięci. Operator zwraca wskaźnik do nowego wektora.

Tą drogą,

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

Mimo że daliśmy wektorowi a wartości, wektor b ma wartości. To magia operator=()!

MSDN - jak utworzyć konstruktor przenoszenia

yash101
źródło
1
Jaka jest twoja odpowiedź dodająca do tego 4-letniego pytania, które nie zostało jeszcze uwzględnione w innych odpowiedziach?
Zamaskowany mężczyzna
5
Nie zauważyłem żadnej takiej odpowiedzi, więc zdecydowałem się dodać. Natknąłem się na to pytanie, szukając go w Google właśnie dzisiaj.
yash101