2016-02-15 1 views
7

Я хотел бы отключить конструктор перемещения в классе. Вместо того, чтобы двигаться, я хотел бы основываться на конструкторе копирования. Когда я пытаюсь написать этот код:Отключить конструктор перемещения

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    Boo(Boo&& boo) = delete; 
}; 

Boo TakeBoo() 
{ 
    Boo b; 
    return b; 
} 

во время компиляции я получил ошибку:

error C2280: 'Boo::Boo(Boo &&)': attempting to reference a deleted function

Как я могу отключить шаг конструктора и силы копии вместо этого?

+6

просто не перегрузить конструктор перемещения и компилятор не будет создавать конструктор перемещения для него, так как уже есть конструктор копирования –

+2

Из стандарта: «Если определение класса X не явно объявлять конструктор перемещения, он будет объявлен как неявно объявленным как дефолт, если и только если X не имеет объявленного пользователем конструктора копирования [...] Когда конструктор перемещения неявно объявлен или явно указан, выражения, которые в противном случае вызывали бы ход конструктор может вместо этого вызвать конструктор копирования ». – Pixelchemist

+1

Что вы надеетесь достичь этим? Это никоим образом не имеет смысла. –

ответ

17

Не создавать любые перемещения конструктора:

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
}; 

Конструктор движение не генерируется автоматически до тех пор, как определенный пользователем конструктор копирования присутствует, поэтому конструктор копирования называется.

+6

Конструктор перемещения не создается автоматически *, если присутствует конструктор копирования *. Это имеет место в примере OP, но стоит отметить, чтобы читатель не пришел к выводу, что не реализовать конструктор перемещения достаточно, чтобы избежать ходов. Например, класс с двумя членами 'std :: vector' и неявным образом создаваемые конструкторы копирования или перемещения получат автоматически сгенерированный конструктор перемещения, который перемещает векторы. – user4815162342

4

Маркировка функции как =delete делает функцию доступной для разрешения перегрузки, но если выбрано, компиляция завершается с ошибкой; эта функциональность не ограничивается конструкторами и другими специальными функциями (see here). Раньше (около C++ 03), делая частное лицо, достигшее аналогичного результата.

Следовательно, код, как в примере, фактически означает, что вы запрещаете построение объекта класса из временного или истекающего значения (rvalues) - конструктора перемещения.

Чтобы исправить это, полностью удалите конструктор перемещения. В случае класса, когда конструктор копирования присутствует (определяется пользователем), перемещение неявно не генерируется в любом случае (перемещение конструктора и оператор назначения перемещения).

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    //Boo(Boo&& boo) = delete; 
}; 
+2

Дополнительная информация: маркировка перемещаемого конструктора как удаленная сама по себе делает его доступным для разрешения перегрузки; однако, если конструктор move неявно определен как удаленный (например, это происходит, если переменная-член имеет свой конструктор перемещения, определенный как удаленный, неявно или явно), тогда это * не * доступно для разрешения перегрузки !. (разрешение перегрузки - это весело ...) –