Pergunta

Por exemplo:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
Foi útil?

Solução

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

Isso retorna uma referência pendurado, assim como com o caso de referência lvalue. Após a função retorna, o objeto temporário vai 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á se movendo corretamente um objeto Beta_ab temporária para o valor de retorno da função. Se o compilador pode, ele vai evitar o movimento por completo, usando RVO (retorno valor optimization). Agora, você pode fazer o seguinte

Beta_ab ab = others.toAB();

E vai mover construir o temporária em ab, ou RVO omitir fazendo um movimento ou copiar completamente. Eu recomendo que você leia BoostCon09 rvalue Referências 101 o que explica o assunto, e como ( N) RVO passa a interagir com este.


Seu caso de retornar uma referência de rvalue seria uma boa idéia em outras ocasiões. Imagine que você tem uma função getAB() que muitas vezes invocar de forma temporária. Não é ideal para fazê-lo retornar uma referência const lvalue para rvalue temporários. Você pode implementá-lo como este

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};

Note que move neste caso não é opcional, porque ab não é nem uma automática local nem um rvalue temporária. Agora, a ref-qualificador && diz que a segunda função é chamado em temporários rvalue, fazendo o seguinte movimento, em vez de cópia

Beta_ab ab = Beta().getAB();

Outras dicas

pode ser mais eficiente, por exemplo, em um contexto diferente bit:

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 código acima versus 62 instruções para std::min regular. No entanto, com -O0 ele gera 518 instruções para código acima contra 481 para std::min regular.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top