Компилятор не будет использовать копирование вместо перемещения?

У меня есть класс, где назначение перемещения явно удалено, так как объект не должен быть перемещаемым. Но если я назначу экземпляр этого класса, используя 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) не может напрямую вызвать существующее назначение копирования? Есть что-то, чего мне не хватает?

3

Решение

Назначение копирования не вызывается, потому что (удаленное) назначение перемещения лучше подходит для разрешения перегрузки.

Просто не объявляйте назначение перемещения вообще. Тогда будет назначено копирование. Неявный оператор присваивания перемещения не будет сгенерирован, потому что класс имеет объявленный пользователем конструктор копирования, конструктор перемещения и оператор присваивания копирования. Любой из них будет препятствовать генерации неявного оператора присваивания перемещения.


Но если я назначу экземпляр этого класса, используя RVO

Здесь нет RVO. Вы создаете временный foo и скопируйте его в существующую переменную. Копирование назначений не может быть отменено.

Кроме того, довольно необычно и неэффективно возвращать по значению оператор присваивания.

3

Другие решения

Вы можете использовать новое размещение, чтобы сделать это:

#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;
}
0

По вопросам рекламы [email protected]