Еще раз об этом, но связанные вопросы не отвечают на мой вопрос.Переместить объект без перемещения конструктора
Стандарт довольно ясно:
12,8 Копирование и перемещение объектов класса,
§9
Если определение класса X не явно объявить конструктор перемещения, один будет неявно объявлен как установлено по умолчанию, если и только если
- X не имеет объявленного пользователем конструктора копирования,
- X не имеет объявленного пользователем оператора копирования копий,
- X не имеет объявленного пользователем mo ve,
- X не имеет объявленного пользователем деструктора, а
- конструктор перемещения не будет неявно определен как удаленный.
[Примечание: если конструктор перемещения неявно объявлен или явно указан, выражения, которые в противном случае вызывают конструктор перемещения, могут вместо этого вызвать конструктор копирования. - конец примечание]
Поэтому, прежде чем замечать «Примечание» в конце концов, я ожидал этот кусок кода на провал компиляции (хотя я знал, что перемещение должен запасного варианта для копирования):
#include <iostream>
using std::cout;
class c
{
public:
c() { cout << "c::c()\n"; }
c(std::initializer_list<int>) { cout << "c::c(std::initializer_list)\n"; };
c(const c&) { cout << "c::c(const c&)\n"; }
c& operator=(const c&) { cout << "c& c::operator=(const c&)\n"; return *this; }
~c() { cout << "c::~c()\n"; }
void f() {}
};
void f(c&& cr) { cout << "f()\n"; cr.f(); }
int main()
{
c x;
f(std::move(x));
return 0;
}
Потом я увидел записку в конце, но я все еще был удивлен, что приведенный выше код выхода:
с :: с()
е()
c :: ~ c()
Обратите внимание на «недостающие» c::c(const c&)
. Затем я добавил
c(c&&) = delete;
c& operator=(c&&) = delete;
и результат по-прежнему остается прежним.
Что я могу здесь пропустить?
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
флаги компилятора: -s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG
.
'cr' является г-значение ** ссылка **, которая еще не потребляется любого конструктора ... –
@ W.F. - О, мой, пожалуйста, отправьте это как ответ. Ты ужасно прав. (Добавление 'c xx (std :: move (x));' вместо использования 'f (c &&)' генерирует ожидаемое поведение. –
это непростой вопрос XD – Stargateur