Здравствуйте, watchmaker, Вы писали:
W>Как же так? Задаёшь поисковику запрос «Reference data members and move constructor» и изучаешь.
Смотрел, это первая ссылка в Google. К сожалению не совсем из нее понятно как правильно. Это просто такое же обсуждение проблемы на форуме. Может есть какая-то авторитетная статья по данной проблеме?
W>Так и требования чего-то там занулять в move-конструкторе нет. После его работы экземпляр-источник должен остаться в консинстентном состоянии. Например, move-конструктор иногда через swap реализуется — очевидно тут два объекта просто меняются данными, а не зануляют что-то. Так и наличие ссылки в экземпляр-источнике на какой-то объект само по себе не приведёт проблемам пока, как ты заметил, через эту ссылку с объектом не начнут работать несогласованно из нескольких мест.
Понятно что требований таких в C++ быть не может — на каждый случай своё решение. В том то и дело, что они оба, при таком подходе, легко могут оказаться в неконсистентном состоянии, так как я не планировал менять один и тот же объект из двух разных мест. Я не хочу оставлять на усмотрение внешнего кода, будут ли работать с уже перемещенным объектом. Тем более, что вы сами написали что источник должен остаться в консистентном состоянии, т.е. с ним могут начать работать.
W>Да, но по сути такой же риск есть и для всех других классов после их перемещения. Наличие ссылки тут не делает проблему новой. Хотя, конечно, если использовать вместо ссылок указатели, то можно присваивать им nullptr и падать в segfault при попытке разыменования, что поможет отладке.
У классов без ссылок я могу переинициализировать члены — я так и делаю.
W>Но лучше просто следовать правилу «не использовать объект после std::move». Нарушил — сам виноват.
Ну.... по-моему это противоречит утверждению, что объект должен оставаться в консистентном состоянии. Я не люблю следить за чем, за чем можно не следить.