Respostas:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Isso retorna uma referência pendente, assim como no caso de referência lvalue. Após o retorno da função, o objeto temporário será destruído. Você deve retornar Beta_ab
por valor, como o seguinte
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Agora, ele está movendo corretamente um Beta_ab
objeto temporário para o valor de retorno da função. Se o compilador puder, ele evitará a movimentação por completo, usando o RVO (otimização do valor de retorno). Agora, você pode fazer o seguinte
Beta_ab ab = others.toAB();
E ele moverá a construção do temporário para ab
, ou fará o RVO para omitir fazer uma movimentação ou copiar completamente. Eu recomendo que você leia as BoostCon09 Rvalue References 101, que explicam o assunto e como (N) RVO interage com isso.
Seu caso de retornar uma referência rvalue seria uma boa idéia em outras ocasiões. Imagine que você tem uma getAB()
função que você invoca frequentemente temporariamente. Não é ideal fazê-lo retornar uma referência constante para temporários rvalores. Você pode implementá-lo assim
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Observe que move
, neste caso, não é opcional, porque ab
não é um rvalue automático local nem temporário. Agora, o ref-qualifier &&
diz que a segunda função é chamada em temporários rvalue, fazendo o seguinte movimento, em vez de copiar
Beta_ab ab = Beta().getAB();
Ele pode ser mais eficiente, por exemplo, em um contexto um pouco diferente:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
Como uma observação interessante, na minha máquina clang++ -O3
gera 54 instruções para o código acima versus 62 instruções para o regular std::min
. No entanto, -O0
ele gera 518 instruções para o código acima e 481 para o regular std::min
.
for(:)
e a integração no objeto desalocado. Correção: ideone.com/tQVOal
std::move()
é usado apenas como um elenco explícito para ilustrar o ponto mais claramente. Não é um código que você copia e cola no seu projeto. Não contradiz a resposta mais votada, porque um objeto temporário é criado dentro da função. O objeto retornado aqui é um dos argumentos (objetos temporários são destruídos como a última etapa na avaliação da expressão completa que (lexicamente) contém o ponto em que foram criados).