Почему std::setbase(2) не переключается на двоичный вывод?

Страница CPPReference на std::setbase говорит:

Значения базы, отличные от 8, 10 или 16, сбрасывают базовое поле на ноль, что соответствует десятичному выводу и вводу, зависящему от префикса.

Как так?

Есть ли конкретная причина, по которой поддерживаются только эти базы? Кажется тривиальным поддерживать хотя бы что-нибудь до 16 (на самом деле, до 36: 0-9 и затем az) без необходимости делать какие-либо трудные выборы. В частности, 2 является популярной базой, я думаю, что должен быть интерес к std::setbase(2) (и соответствующий std::binary).

Я, очевидно, могу напечатать свои собственные биты, но для моего ostream было бы хорошо сделать это.

2 ответа

Решение

Единственный верный ответ - "потому что так говорится в стандарте".

При этом стандарт в основном формализовал предстандартные реализации iostream, многие из которых, вероятно, были разработаны просто для достижения функционального равенства с printf, который поддерживает только десятичные, восьмеричные и шестнадцатеричные (через специальный, не очень общий синтаксис).

Кроме того, как и сейчас, было бы несложно исправить API-интерфейс iostream для поддержки "многих" баз, учитывая, что базовая настройка заканчивается битовым полем, а не отдельным полем "текущей базы".

Теперь стандарт требует fmtflags иметь некоторый "тип битовой маски" - который может даже быть std::bitsetТаким образом, вы можете найти способ как-то перелопачивать все эти новые "базовые" поля - но действительно ли это стоит усилий (плюс риск взлома кода, который предполагает, что fmtflags является интегральным типом) для функции, которая практически никого не волнует?

Итак, подведем итог: плохой первоначальный дизайн (как, впрочем, и остальная часть iostream), нетривиальное исправление и отсутствие реальной потребности пользователя в такой функции.

Насколько мне известно, предложения о добавлении поддержки двоичного (base 2) форматирования в iostreams (см. Также не поступалоБыло ли предложение добавить std ::bin в стандарт C ++? ). Однако он поддерживается в C++20.:

      std::string s = std::format("{:b}", 42);

не является широко доступным, но вы можете использовать библиотеку {fmt} , основанную на:

      std::string s = fmt::format("{:b}", 42);

Отказ от ответственности : я являюсь автором {fmt} и C++20 std::format.

Другие вопросы по тегам