Обычно, когда я удаляю элемент из набора, я хочу утверждать, что он был действительно удален:
т.е.
assert(s.erase(e));
но тогда элемент не стирается, когда установлен NDEBUG. Но если я напишу
bool removed = s.erase(e);
assert(removed);
компилятор жалуется, что «удалено» не используется, когда установлен NDEBUG.
Как я могу сделать это правильно?
В итоге я просто создал служебный метод:
inline void run_and_assert(bool b) {
assert(b);
}
теперь я могу сказать
run_and_assert(s.erase(e));
Есть ли какие-либо недостатки в этом? Мне кажется, это проще, чем решение Луискубаля
Первый пример неверен, потому что выражение assert будет удалено при определении NDEBUG, поэтому s.erase(e)
не будет вызван вообще.
Аргумент assert
НИКОГДА не должно иметь побочных эффектов.
Второй подход лучше, хотя предупреждение действительно может раздражать, но Есть способы заставить замолчать предупреждение.
В качестве альтернативы вы можете придумать свой собственный оператор assert, который всегда выполняет код.
#ifdef NDEBUG
#define assert_always_execute(x) (x)
#else
#define assert_always_execute(x) assert(x)
#endif
Я написал свое собственное предложение Луискубаля, за исключением того, что вместо уродливых # define я сделал короткий встроенный метод:
inline void assert_always_execute(bool x) {
assert(x);
}