Como os objetos movidos podem ser usados? [duplicado
-
28-09-2019 - |
Pergunta
Esta pergunta já tem uma resposta aqui:
- O que posso fazer com um objeto movido? 2 respostas
Depois de mover um objeto, deve ser destrutável:
T obj;
func(std::move(obj));
// don't use obj and let it be destroyed as normal
Mas o que mais pode ser feito com o OBJ? Você poderia mover outro objeto para ele?
T obj;
func(std::move(obj));
obj = std::move(other);
Isso depende do tipo exato? (Por exemplo, STD :: Vector poderia fazer garantias específicas em que você não pode confiar para todos os T.) É necessário ou mesmo sã que todos os tipos suportam algo além da destruição em objetos movidos?
Solução
Sim, você pode mover outro objeto para ele. std :: swap faz isso.
Outras dicas
O rascunho atual do C ++ 0x exige que um objeto movido-da-from possa ser destruído ou atribuído. Se você passar seu objeto para uma função na biblioteca padrão, isso é tudo o que é assumido.
Geralmente, é considerado uma boa prática garantir que um objeto movido a partir de um objeto "funcionando" de seu tipo que satisfaz todos os invariantes. No entanto, está em um estado não especificado-se for um contêiner, você não sabe quantos elementos ele tem, ou o que são, mas você deve ser capaz de ligar size()
e empty()
, e consulte.
O rascunho atual não está claro sobre o que é exigido dos tipos de biblioteca padrão, e há uma discussão ativa no comitê C ++ sobre isso.
Isso é semântica do tipo. Você decide. Cabe a você como você implementa a mudança.
Em geral, o estado deve ser o mesmo que o obtido usando o construtor não paramétrico.
Por falar nisso. O Move faz sentido apenas se você estiver armazenando um bloco de dados atrás de um ponteiro (ou alguma outra classe móvel).
Depende do código da classe. Se a classe não tiver construtor de referência e operador de atribuição RValue, o STD :: Move será ignorado. STD :: Move não move nada, apenas permite tratar seu argumento como referência de RValue, se a função apropriada estiver disponível.
Corretamente escrito && construtor e operador = devem deixar a instância do parâmetro em algum estado consistente, como string vazia e objeto deve ser utilizável. Se houver operador =, outro objeto poderá ser atribuído corretamente a essa instância vazia.
Editar.
Geralmente, o Move STD :: deve ser usado para aplicar a semântica de mover para a variável que não é Rvalue, mas na verdade é:
SomeClass::SomeClass(SomeClass&& v) { // Inside of this function, v is not rvalue anymore. But I know that actually // this is rvalue, and use std::move OtherFunction(std::move(v)); }
Nesse caso, a exigência mininal de V é que ele deve ser capaz de morrer sem problemas.
Quando o STD :: Move é usado para a variável que não é realmente referência de RValue, realmente, essa usabilidade variável pode ser indefinida. Para minhas próprias aulas, eu garantiria algum tipo de consistência para este caso. Para outras classes - depende da implementação de classe específica, mas eu não aplicaria o STD :: Mover para objetos que na verdade não são referências Rvalue. Eu realmente não sei como isso é definido (e se é definido) no padrão.
Como finalmente entendi nos comentários. Você deve verificar isso: http://www.boost.org/doc/libs/1_44_0/libs/concept_check/concept_check.htm
Isso permitirá que você verifique o tipo fornecido como parâmetros de modelo para conceitos (recursos do tipo). Não tenho certeza se eles já têm um para móveis.