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?

Anarki
fuente
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
1
Posible duplicado de ¿Qué significa T&& (doble ampersand) en C ++ 11?
Trevor Boyd Smith

Respuestas:

112

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

aschepler
fuente
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.

Lexseal Lin
fuente
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.

Billy ONeal
fuente
@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.

Michael Burr
fuente
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

yash101
fuente
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