У меня есть класс, где назначение перемещения явно удалено, так как объект не должен быть перемещаемым. Но если я назначу экземпляр этого класса, используя RVO, компилятор выдаст мне ошибку:
main.cpp:12:16: note: candidate function has been explicitly deleted
также компилятор упоминает существующий оператор присваивания копии, но не использует его.
вот мой код (или (не) запущенный пример Вот):
class foo {
public:
foo() {}
foo(foo const& r) {}
foo(foo&&) = delete;
foo const& operator=(foo const& r) { return *this; }
foo const& operator=(foo&& r) = delete;
};
int main(int argc, char **argv) {
foo bar;
bar = foo();
return 0;
}
Я нашел довольно похожий пост Вот.
Я знаю, что могу избежать этого, используя временный. Интересно, почему каждый компилятор (я проверял это с gcc, clang и vs2013) не может напрямую вызвать существующее назначение копирования? Есть что-то, чего мне не хватает?
Назначение копирования не вызывается, потому что (удаленное) назначение перемещения лучше подходит для разрешения перегрузки.
Просто не объявляйте назначение перемещения вообще. Тогда будет назначено копирование. Неявный оператор присваивания перемещения не будет сгенерирован, потому что класс имеет объявленный пользователем конструктор копирования, конструктор перемещения и оператор присваивания копирования. Любой из них будет препятствовать генерации неявного оператора присваивания перемещения.
Но если я назначу экземпляр этого класса, используя RVO
Здесь нет RVO. Вы создаете временный foo
и скопируйте его в существующую переменную. Копирование назначений не может быть отменено.
Кроме того, довольно необычно и неэффективно возвращать по значению оператор присваивания.
Вы можете использовать новое размещение, чтобы сделать это:
#include <iostream>
#include <string>
#include <new>
class foo {
public:
foo() {}
foo(foo const& r) {}
foo(foo&&) = delete;
foo const& operator=(foo const& r) { return *this; }
foo const& operator=(foo&& r) = delete;
};
int main(int argc,char **argv)
{
foo bar;
//bar = foo();
bar.~foo();
new(&bar) foo();
return 0;
}