Заголовок поста может звучать провокационно, но когда я задумываюсь о местах, в которых bool уместен, так их оказывается всего ничего:
- тип возвращаемого значения для методов empty в контейнерах;
- тип возвращаемого значения для метода has_value в optional;
- оператор приведения к bool в умных указателях, чтобы можно было писать if(my_ptr) (+ сюда же аналогичный оператор в optional);
- иногда результаты проверок с бинарным результатом "да"/"нет", которые (результаты в смысле) нужно зачем-то сохранить.
Вот, пожалуй, и все. Остальное полезное, скорее всего, будет всего лишь вариациями на вышеозвученные темы.
Если bool используется в качестве типов параметров для функций, то в коде получаются ужасы вроде:
|
remove_relations(obsolete_relations, false, false, &errors); delete_nodes(obsolete_nodes, false, &errors); add_nodes(new_nodes, true, false, &errors); add_nodes(changed_nodes, false, false, &errors); add_relations(new_relations, false, true, &errors); |
Что здесь означает каждый true и false, почему они именно такие -- хз, удачи в разборах.
Если bool используется в качестве возвращаемого значения, то получается не менее удручающе:
|
auto item_processor = [&](item_id id, bool pos_already_provided = false){ auto res = calculate_one_value( id, weights, weights_params, global_pos, pos_already_provided); if (res.m_should_obtain_pos) { need_deep_search = true; sum = 0; return false; } if (!res.m_continuation_operator_found) { value = res.m_value; return false; } if (res.m_value) sum += data_extractor::get_number(res.m_value); return true; }; |
Вот честно, пара-тройка таких функций, и мозги начинают плавиться.
Поэтому для себя сделал вывод:
- bool в качестве типа аргумента функции/метода -- ни в коем случае. Лучше такого вообще не делать, вместо bool должен использоваться enum class;
- bool в качестве возвращаемого значения -- если для случаев empty/has_value, то OK, в остальных случаях лучше enum class. Во многом уместность bool определяется именем и назначением функции/метода. Если это getter с именами вроде has_something или is_something, или can_do_something, или must_do_something (т.е. в названии сформулирован вопрос, ответом на который может быть только "да" или "нет"), то норм. Но если если метод мутирующий или функция имеет побочные эффекты, а возвращается bool, то тут могут (и скорее всего будут) возникать вопросы при чтении кода с использованием таких методов/функций;
- bool в качестве локальной переменной -- сомнительно, но OK, особенно если это константа. Если не константа, то таки лучше подумать в сторону enum class;
- bool в качестве члена класса -- сомнительно, но в некоторых случаях может быть OK. Например, если это флаг has_value в optional (или что-то вроде этого).
Вполне себе подходящий случай для bool в качестве члена класса -- это статическая константа value в метафункции, вроде:
|
struct some_trait { static constexpr bool value = ...; }; |
Если же говорить в целом, то сам по себе тип bool должен быть в языке. И еще лучше, если он никак не смешивается с другими типами и не может приводиться в другие типы (или автоматически выводиться из других типов). Потому что если bool нет и начинаются извращения с int-ами и вручную написанными константами TRUE и FALSE, то это еще хуже (сам через это проходил 30 лет назад). Но таки мест, где bool был бы предпочтительнее специально написанного enum class-а, на сегодня, не так много, как кажется.
PS. Самым же бесполезным типом в C++, наверное, является тип short.
Комментариев нет:
Отправить комментарий