Por que esse código C ++ 0x chama o construtor de movimentação?
Pergunta
Por algum motivo, o código seguinte nunca liga Event::Event(Event&& e)
Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);
por que não?
Usando std::swap
chama isso uma vez.
class Event {
public:
Event(): myTime(0.0), myNode(NULL) {}
Event(fpreal t, Node* n);
Event(Event&& other);
Event(Event const& other) = delete;
~Event();
bool operator<(Event const& other) const { return myTime < other.myTime; }
bool operator>(Event const& other) const { return myTime > other.myTime; }
fpreal getTime() const { return myTime; }
void setTime(fpreal time) { myTime = time; }
Node* getNode() const { return myNode; }
private:
fpreal myTime;
Node* myNode;
};
Solução
Seu código possui dois locais em potencial para onde se pode esperar que o construtor de movimentos seja chamado (mas não):
1) Chamando Std :: Move
2) durante a tarefa.
Em relação a 1), STD :: Move faz um elenco simples - ele não cria um objeto de uma cópia - se o fez, o construtor de movimentos pode ser invocado por ele, mas como ele faz um simples lançamento, ele não é invocado . A definição de std :: move é semelhante a static_cast<Event&&>(temp)
.
Em relação a 2), a inicialização e a atribuição são duas operações totalmente diferentes (mesmo que algumas formas de inicialização usem o símbolo '='). Seu código faz atribuição e, portanto, usa o operador de atribuição padrão, que é declarado para aceitar uma referência const lvalue. Como você nunca inicializa um objeto de evento com outro, você não verá o seu construtor de movimentos ser invocados. Se você declarou um operador de atribuição de movimento: Event& operator=(Event&& other)
, então seu código atual invocaria ou se você escreveu: Event a; Event tmp = move(a);
Seu construtor de movimentos, como escrito, seria invocado.
Outras dicas
Você não está usando o construtor de movimentos. Eu acho que a troca é implementada algo assim
Event a;
Event b;
Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);
Você deseja usar o operador de atribuição de movimentação, que não existe em seu código, por isso volta ao operador de atribuição de cópia.