Sou um programador simples. As variáveis de meus membros de classe geralmente consistem em tipos POD e contêineres STL. Por causa disso, raramente preciso escrever operadores de atribuição ou construtores de cópia, pois eles são implementados por padrão.
Adicione a isso, se eu usar std::move
em objetos não móveis, ele utiliza o operador de atribuição, o que significa que std::move
é perfeitamente seguro.
Como sou um programador simples, gostaria de aproveitar as vantagens dos recursos de movimentação sem adicionar um construtor de movimentação / operador de atribuição a cada classe que escrevo, já que o compilador poderia simplesmente implementá-los como " this->member1_ = std::move(other.member1_);...
"
Mas não (pelo menos não no Visual 2010), há algum motivo particular para isso?
Mais importante; existe alguma maneira de contornar isso?
Atualização: Se você olhar para a resposta do GManNickG, ele fornece uma ótima macro para isso. E se você não sabia, se você implementar a semântica de movimento, poderá remover a função de membro de troca.
fonte
MyClass::MyClass(Myclass &&) = default;
?Respostas:
A geração implícita de construtores de movimento e operadores de atribuição tem sido controversa e houve grandes revisões em rascunhos recentes do padrão C ++, portanto, os compiladores disponíveis atualmente provavelmente se comportarão de maneira diferente com relação à geração implícita.
Para mais informações sobre a história do problema, consulte a lista de artigos do WG21 de 2010 e pesquise por "mov"
A especificação atual (N3225, de novembro) afirma (N3225 12.8 / 8):
Há linguagem semelhante em 12.8 / 22 especificando quando o operador de atribuição de movimentação é declarado implicitamente como padrão. Você pode encontrar a lista completa de alterações feitas para suportar a especificação atual de geração de movimento implícito em N3203: Estreitando as condições para gerar movimentos implícitos , que foi amplamente baseada em uma das resoluções propostas pelo artigo N3201 de Bjarne Stroustrup : Seguir em frente .
fonte
cannot be defaulted *in the class body*
. Então, eu defini o destruidor externo e funcionou :). Acho um pouco estranho, no entanto. Alguém tem uma explicação? O compilador é gcc 4.6.1virtual ~D() = default;
deveria funcionar e ainda permitir um construtor de movimento implícito.Construtores de movimento gerados implicitamente foram considerados para o padrão, mas podem ser perigosos. Veja a análise de Dave Abrahams .
No final, no entanto, o padrão incluiu a geração implícita de construtores de movimento e operadores de atribuição de movimento, embora com uma lista bastante substancial de limitações:
No entanto, isso não é tudo na história. Um ctor pode ser declarado, mas ainda definido como excluído:
fonte
Tweak2
. Suponho que tenha algo a ver com o fato de que oNumber
seria movido evector
copiado ... mas não tenho certeza: / Eu entendo que o problema iria se espalhar paraTweak3
.Sim, eu também fui por esse caminho. Aqui está sua macro:
(Eu removi os comentários reais, que são longos e documentais.)
Você especifica as bases e / ou membros em sua classe como uma lista de pré-processador, por exemplo:
E surge um construtor de movimento e um operador de atribuição de movimento.
(À parte, se alguém souber como posso combinar os detalhes em uma macro, isso seria ótimo.)
fonte
VS2010 não faz isso porque eles não eram padrão no momento da implementação.
fonte