В статье 12 Effective Modern C++ Скотт Мейерс пишет: следующий класс, чтобы показать, насколько полезной может быть перегрузка функций-членов для ссылочных квалификаторов:
class Widget {
public:
using DataType = std::vector<double>;
…
DataType& data() & // for lvalue Widgets
{ return values; } // return lvalue
DataType data() && // for rvalue Widgets
{ return std::move(values); } // return rvalue
…
private:
DataType values;
};
Это кажется очевидным: теперь non_temp_obj.data()
вызовет первую перегрузку и вернет ссылку на член объекта, который после этого все еще жив, тогда как make_temp_obj().data()
возвращает по значению член объекта, который умирает, как только это выражение выполняется.
Вот мой первый вопрос: что касается перегрузки &&
, почему return std::move(values);
, а не только return values;
, учитывая, что мы возвращаем значение?
Однако в об ошибках Мейерс пишет:
Лучший способ заставить перегруженную ссылку rvalue функции-члена
data
возвращать rvalue — вернуть ссылку rvalue. Это позволило бы избежать создания временного объекта для возвращаемого значения и соответствовало бы возврату по ссылке исходного интерфейсаdata
вверху страницы 84.
что я интерпретирую как предложение изменить
DataType data() &&
{ return std::move(values); }
to
DataType&& data() &&
{ return std::move(values); }
но я не понимаю причины, особенно в свете этого ответа, который в значительной степени убеждает меня в том, что версия книги верна и опечатка неправильная.
Итак, мой второй вопрос: кто прав?