Недавно я прочитал о [[nodiscard]]
в C++17, и, насколько я понимаю, это новая функция (дизайн по контракту?), которая заставляет вас использовать возвращаемое значение. Это имеет смысл для спорных функций, таких как std::launder
(nodiscard начиная с C++20), но мне интересно, почему std::move
не определено так в C++17/20. Знаете ли вы вескую причину или это потому, что С++ 20 еще не завершен?
Почему std::move не [[nodiscard]] в С++ 20?
Ответы (2)
Насколько я знаю, P0600R1 является единственным предложением для добавление [[nodiscard]]
в стандартную библиотеку, которая применялась к C++20. Из этой бумаги:
Мы предлагаем консервативный подход:
[...]
Его не следует добавлять, когда:
- [...]
- неиспользование возвращаемого значения не имеет смысла, но не вредит и обычно не является ошибкой
- [...]
Итак, [[nodiscard]] не должен сигнализировать о плохом коде, если это
- [...]
- не больно и наверное не имелось в виду изменение состояния что не бывает
Итак, причина в том, что стандартная библиотека использует консервативный подход, а более агрессивный пока не предлагается.
std::move
всегда является ошибкой в моей книге, и поэтому согласно вашей цитате его не следует отбрасывать: либо подразумевается, что пользователь забыл использовать возвращаемое значение, либо вызов не нужен, поскольку он не имеет никакого эффекта. .
- person Konrad Rudolph; 21.04.2019
std::move()
вызывает фактические ошибки. Рассмотрите возможность поднять этот вопрос в списке рассылки обсуждения стандартов C++.
- person einpoklum; 02.04.2020
[[nodiscard]]
является вероятно недосмотром, а не сознательным решением, мотивированным цитатой в этом ответе.
- person Konrad Rudolph; 02.04.2020
Команда стандартной библиотеки MSVC пошла дальше и добавила несколько тысяч экземпляров [[nodiscard]]
начиная с VS 2017 15.6 и сообщила о невероятном успехе (как с точки зрения обнаружения большого количества ошибок, так и с точки зрения отсутствия жалоб пользователей). Критерии, которые они описали, были примерно такими:
- Чистые наблюдатели, т.е.
vector::size()
,vector::empty
и дажеstd::count_if()
- Вещи, которые приобретают сырые ресурсы, например.
allocate()
- Функции, в которых отбрасывание возвращаемого значения с большой вероятностью приведет к неправильному коду, например.
std::remove()
MSVC помечает std::move()
и std::forward()
как [[nodiscard]]
в соответствии с этими критериями.
Хотя это официально не аннотировано как таковое в стандарте, похоже, оно обеспечивает очевидную пользу для пользователя, и это скорее вопрос создания такого документа, чтобы отметить все правильные вещи [[nodiscard]]
(опять же, несколько тысяч экземпляров из MSVC) и применить их - это сама по себе работа не сложная, но объем большой. А пока, может быть, подтолкнете вашего любимого поставщика стандартной библиотеки и попросите его сделать [[nodiscard]]
кучу всего?
[[nodiscard]]
поможет диагностировать ошибки. Кроме того, ничего страшного не происходит, когдаvector::empty()
игнорируется, но по понятным причинам помечается как[[nodiscard]]
. - person Vittorio Romeo   schedule 20.04.2019[[nodiscard]]
: Эй, ты сделал что-то совершенно бессмысленное. Вы хотели сделать что-то еще? - person Barry   schedule 20.04.2019std::move
не двигается. Прохождение объекта черезstd::move
и игнорирование результата абсолютно ничего не делает. - person tkausl   schedule 21.04.2019std::move
, кромеoperator=
, так что это все еще ошибка, не так ли? - person bbalchev   schedule 21.04.2019std::move(x);
не работает. - person L. F.   schedule 21.04.2019std::move
, это возвращает ссылку rvalue на объект; так что объект может впоследствии быть перемещен из если ссылка используется таким образом. - person Sebastian Redl   schedule 21.04.2019bbalchev::move
, на котором есть[[nodiscard]]
. Я бы назвал своегоeljay::move_dammit
, но это только я. - person Eljay   schedule 04.05.2019