Opérateur de double adresse C ++? (&&)

137

Je lis le code source de STL et je n'ai aucune idée de ce que l' &&opérateur d'adresse est censé faire. Voici un exemple de code tiré de stl_vector.h:

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

"Adresse d'adresse" at-il un sens? Pourquoi a-t-il deux opérateurs d'adresse au lieu d'un seul?

Anarki
la source
2
C'est peut-être une adresse de référence.
Gabe
1
@Gabe; c'est une déclaration qui en ferait une référence à une référence, ce qui n'a aucun sens car la référence elle-même ne peut pas être modifiée. L'adresse de ne peut être utilisée que dans le code, pas lors de la déclaration (un paramètre comme dans ce cas, ou autrement). Je n'ai jamais rien vu de tel.
falstro
5
Même s'il n'y en avait qu'un seul &, cela n'aurait rien à voir avec l'opérateur address-of, mais signifierait plutôt qu'il __xs'agit d'une référence.
sepp2k
1
Double
Trevor Boyd Smith le

Réponses:

112

C'est du code C ++ 11 . En C ++ 11, le &&jeton peut être utilisé pour désigner une "référence rvalue".

aschepler
la source
175

&&est nouveau dans C ++ 11. int&& asignifie que "a" est une référence de valeur r. &&n'est normalement utilisé que pour déclarer un paramètre d'une fonction. Et cela ne prend qu'une expression de valeur r. Si vous ne savez pas ce qu'est une valeur r, l'explication simple est qu'elle n'a pas d'adresse mémoire. Par exemple, le nombre 6 et le caractère «v» sont tous deux des valeurs r. int a, a est une valeur l, mais (a+2)est une valeur r. Par exemple:

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

J'espère que c'est informatif.

Lexseal Lin
la source
11
Le seul exemple que j'aimerais que vous ajoutiez est la manière dont cela fonctionne avec std :: move. Montrer ce qui se passerait avec int&& c = std::move( b );, etc.
Zzzach ...
2
On dirait que Sravani S a ouvertement plagié de votre part pour TutorialsPoint le 15 février 2018, ici .
Gabriel Staples le
3
Je viens d'envoyer ce message à TutorialsPoint . L'article, tel que plagié par eux, ressemble à ceci .
Gabriel Staples le
86

&&est nouveau dans C ++ 11, et cela signifie que la fonction accepte une RValue-Reference - c'est-à-dire une référence à un argument qui est sur le point d'être détruit.

Billy ONeal
la source
@bronekk: Avez-vous vu la date de publication sur ce message? Il n'a pas été publié le 28 décembre 2010.
Billy ONeal
désolé à ce sujet, supprimé maintenant. Sera plus prudent la prochaine fois :)
bronekk
34

Comme d'autres réponses l'ont mentionné, le &&jeton dans ce contexte est nouveau pour C ++ 0x (le prochain standard C ++) et représente une «référence rvalue».

Les références Rvalue sont l'une des nouveautés les plus importantes de la prochaine norme; ils permettent le support de la sémantique «move» sur les objets et permettent un transfert parfait des appels de fonction.

C'est un sujet assez complexe - l'une des meilleures introductions (qui n'est pas simplement superficielle) est un article de Stephan T. Lavavej, "Références Rvalue : Fonctionnalités C ++ 0x dans VC10, Partie 2"

Notez que l'article est encore assez lourd à lire, mais qu'il en vaut la peine. Et même si c'est sur un blog Microsoft VC ++, toutes (ou presque toutes) les informations sont applicables à n'importe quel compilateur C ++ 0x.

Michael Burr
la source
Le &&jeton lui-même n'est pas nouveau; sa signification dans les déclarations est. Mais tu le savais.
aschepler
C'est nouveau dans ce contexte. Mais il est très traditionnel pour C / C ++ de surcharger ses jetons pour avoir une signification différente dans différents contextes.
Martin York
1
@aschkleper - bien sûr ... l'opérateur logique et n'est même pas entré dans mon esprit. Je mettrai à jour la réponse.
Michael Burr
5

Je pense que c'est un opérateur de déménagement. operator=est l'opérateur d'affectation, par exemple vector x = vector y. L' clear()appel de fonction sonne comme s'il supprimait le contenu du vecteur pour éviter une fuite de mémoire. L'opérateur renvoie un pointeur vers le nouveau vecteur.

Par ici,

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

Même si nous avons donné des valeurs au vecteur a, le vecteur b a les valeurs. C'est la magie du operator=()!

MSDN - Comment créer un constructeur de déplacement

yash101
la source
1
Que répondez-vous à cette question vieille de 4 ans, qui n'a pas déjà été abordée dans les autres réponses?
Masked Man
5
Je n'ai remarqué aucune réponse comme celle-ci alors j'ai décidé d'ajouter. Je suis tombé sur cette question en googlant juste aujourd'hui.
yash101