C ++ Operador de doble dirección? (&&)


137

Estoy leyendo el código fuente STL y no tengo idea de qué &&se supone que debe hacer el operador de dirección. Aquí hay un ejemplo de código de stl_vector.h:

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

¿Tiene sentido "Dirección de dirección"? ¿Por qué tiene dos operadores de dirección en lugar de solo uno?


2
Tal vez es una dirección de referencia.
Gabe

1
@Gabe; es una declaración para que sea una referencia a una referencia, lo que no tiene ningún sentido ya que la referencia en sí no puede modificarse. La dirección de solo se puede usar en el código, no al declarar (un parámetro como en este caso, o de otro modo). Sin embargo, nunca he visto algo así.
falstro

55
Incluso si hubiera solo uno &, no tendría nada que ver con la dirección del operador, sino que significa que __xes una referencia.
sepp2k

Respuestas:


112

Este es el código C ++ 11 . En C ++ 11, el &&token puede usarse para significar una "referencia de valor de r".


175

&&es nuevo en C ++ 11. int&& asignifica "a" es una referencia de valor r. &&normalmente solo se usa para declarar un parámetro de una función. Y solo toma una expresión de valor r. Si no sabe qué es un valor r, la explicación simple es que no tiene una dirección de memoria. Por ejemplo, el número 6 y el carácter 'v' son ambos valores r. int a, a es un valor l, sin embargo, (a+2)es un valor r. Por ejemplo:

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

Espero que sea informativo.


11
El único ejemplo que desearía agregar es cómo funciona esto con std :: move. Mostrando lo que sucedería con int&& c = std::move( b );, etc.
Zzzach ...

2
Parece que Sravani S plagió descaradamente de ti para TutorialsPoint el 15 de febrero de 2018, aquí .
Gabriel Staples

3
Acabo de enviar este mensaje a TutorialsPoint . El artículo, como plagiado por ellos, se ve así .
Gabriel Staples

86

&&es nuevo en C ++ 11, y significa que la función acepta una referencia RValue , es decir, una referencia a un argumento que está a punto de ser destruido.


@bronekk: ¿Viste la fecha de publicación en este mensaje? No se publicó a partir del 28 de diciembre de 2010.
Billy ONeal

lo siento por eso, eliminado ahora. Tendrá más cuidado la próxima vez :)
bronekk

34

Como han mencionado otras respuestas, el &&token en este contexto es nuevo en C ++ 0x (el próximo estándar de C ++) y representa una "referencia de valor de r".

Las referencias de Rvalue son una de las cosas nuevas más importantes en el próximo estándar; Permiten la compatibilidad con la semántica de 'movimiento' en los objetos y permiten el reenvío perfecto de llamadas a funciones.

Es un tema bastante complejo: una de las mejores introducciones (que no es simplemente superficial) es un artículo de Stephan T. Lavavej, "Referencias de valor: Características de C ++ 0x en VC10, Parte 2"

Tenga en cuenta que el artículo sigue siendo una lectura bastante pesada, pero vale la pena. Y a pesar de que está en un blog de Microsoft VC ++, toda (o casi toda) la información es aplicable a cualquier compilador de C ++ 0x.


El &&token en sí no es nuevo; su significado en declaraciones es. Pero eso ya lo sabías.
aschepler

Es nuevo en este contexto. Pero es muy tradicional que C / C ++ sobrecargue sus tokens para tener un significado diferente en diferentes contextos.
Martin York

1
@aschkleper, por supuesto ... el operador lógico y ni siquiera entró en mi mente. Actualizaré la respuesta.
Michael Burr

5

Creo que es un operador de movimiento. operator=es el operador de asignación, por ejemplo vector x = vector y. La clear()llamada a la función suena como si estuviera eliminando el contenido del vector para evitar una pérdida de memoria. El operador devuelve un puntero al nuevo vector.

De esta manera,

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

Aunque le dimos valores al vector a, el vector b tiene los valores. ¡Es la magia del operator=()!

MSDN - Cómo crear un constructor de movimiento


1
¿Cuál es su respuesta agregando a esta pregunta de 4 años, que no se ha cubierto en las otras respuestas?
Hombre enmascarado

55
No noté ninguna respuesta como esta, así que decidí agregar. Me encontré con esta pregunta buscando en Google hoy.
yash101
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.