Operador de endereço duplo C ++? (&&)

137

Estou lendo o código fonte STL e não tenho idéia do que o &&operador de endereço deve fazer. Aqui está um exemplo 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;
}

"Endereço do endereço" faz algum sentido? Por que ele tem dois operadores de endereço em vez de apenas um?

Anarki
fonte
2
Talvez seja o endereço de uma referência.
Gabe
1
@Gabe; é uma declaração, para que seja uma referência a uma referência, o que não faz sentido, pois a própria referência não pode ser modificada. O endereço de só pode ser usado no código, não ao declarar (um parâmetro como neste caso ou de outra forma). Nunca vi nada assim embora.
falstro
5
Mesmo se houvesse apenas um &, isso não teria nada a ver com o endereço do operador, mas, em vez disso, significa que __xé uma referência.
sepp2k
1
Possível duplicata do que significa T&& (duplo e comercial) no C ++ 11?
Trevor Boyd Smith

Respostas:

112

Este é o código C ++ 11 . No C ++ 11, o &&token pode ser usado para significar uma "referência de valor r".

aschepler
fonte
175

&&é novo no C ++ 11. int&& asignifica "a" é uma referência de valor-r. &&normalmente é usado apenas para declarar um parâmetro de uma função. E leva apenas uma expressão de valor-r. Se você não sabe o que é um valor r, a explicação simples é que ele não possui um endereço de memória. Por exemplo, o número 6 e o ​​caractere 'v' são ambos valores-r. int a, a é um valor l, no entanto (a+2)é um valor r. Por exemplo:

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 seja informativo.

Lexseal Lin
fonte
11
O único exemplo que eu gostaria que você adicionasse é como isso funciona com std :: move. Mostrando o que aconteceria com int&& c = std::move( b );etc.
Zzzach ...
2
Parece que Sravani S ostensivamente plagiou com você pelo TutorialsPoint em 15 de fevereiro de 2018, aqui .
Gabriel Staples
3
Acabei de enviar a TutorialsPoint esta mensagem . O artigo, como plagiado por eles, fica assim .
Gabriel Staples
86

&&é novo no C ++ 11 e significa que a função aceita uma RValue-Reference - ou seja, uma referência a um argumento que está prestes a ser destruído.

Billy ONeal
fonte
@bronekk: Você viu a data de postagem nesta mensagem? Ela não foi publicada a partir de 28 de dezembro de 2010.
Billy ONeal
desculpe por isso, removido agora. Será mais cuidado da próxima vez :)
bronekk
34

Como outras respostas mencionaram, o && token neste contexto é novo no C ++ 0x (o próximo padrão C ++) e representa uma "referência de valor r".

As referências de valor são uma das coisas novas mais importantes no próximo padrão; eles permitem o suporte à semântica de 'movimentação' de objetos e permitem o encaminhamento perfeito de chamadas de função.

É um tópico bastante complexo - uma das melhores introduções (que não é meramente superficial) é um artigo de Stephan T. Lavavej, "Rvalue References: C ++ 0x Features in VC10, Part 2"

Observe que o artigo ainda é uma leitura bastante pesada, mas vale a pena. E mesmo estando em um blog do Microsoft VC ++, todas (ou quase todas) as informações são aplicáveis ​​a qualquer compilador C ++ 0x.

Michael Burr
fonte
O &&token em si não é novo; seu significado nas declarações é. Mas você sabia disso.
Aschepler
É novo neste contexto. Mas é altamente tradicional que o C / C ++ sobrecarregue seus tokens para ter significado diferente em contextos diferentes.
Martin York
1
@aschkleper - é claro ... o operador lógico e nem sequer entrou na minha mente. Vou atualizar a resposta.
Michael Burr
5

Eu acredito que é um operador de movimento. operator=é o operador de atribuição, digamos vector x = vector y. A clear()chamada de função soa como se estivesse excluindo o conteúdo do vetor para evitar um vazamento de memória. O operador retorna um ponteiro para o novo vetor.

Deste jeito,

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

Mesmo que demos valores ao vetor a, o vetor b tem os valores. É a mágica do operator=()!

MSDN - Como criar um construtor de movimentação

yash101
fonte
1
Qual é a sua resposta para esta pergunta de 4 anos, que ainda não foi abordada nas outras respostas?
Homem mascarado
5
Não notei nenhuma resposta como essa, então decidi adicionar. Me deparei com essa questão pesquisando no Google hoje.
yash101