Насколько я знаю, для добавления флага форматирования для добавления бинарного форматирования и/или манипулятора std::bin
не было предложено ни одного предложения. Вы можете проверить предложения по номеру http://www.open-std.org/jtc1/sc22/wg21/docs/papers/. Я уверен, что предложение добавить бинарные литералы не добавило этого средства (быстрый поиск показал N3472, но я не уверен, что это последняя версия статьи).
С технической точки зрения, это может быть нелегко добавить! Различные флаги, как правило, хранятся всего одним словом в классе потока, и есть разные причины использовать все биты. Существующие три настройки (std::ios_base::oct
, std::ios_base::dec
, std::ios_base::hex
) могут быть хорошо сохранены всего в 2 битах. Конечно, три значения оставят одно значение открытым, за исключением того, что это значение обычно принимается для значения по умолчанию, то есть не фиксирует базу при чтении. В результате может потребоваться изменить макет классов потоков или сделать обработку менее эффективной (например, путем использования iword()
для хранения дополнительной возможности двоичного форматирования). Я не сделал анализ, есть ли реальная проблема с любой из реализаций (я знаю, что для моей реализации нет ни одного, но я использовал все биты в слове, если я правильно помню).
Если вы хотите поддерживать двоичное форматирование, относительно легко добавить через пользовательский фасет std::num_put<char>
. Ниже приведен простой пример. Он не имеет отношения к некоторым параметрам форматирования, которые могут быть желательными, например, для заполнения или разделителей цифр:
#include <iostream>
#include <limits>
#include <locale>
class binary_num_put
: public std::num_put<char> {
template <typename T>
iter_type common_put(iter_type out, std::ios_base& str, char_type fill,
T original, unsigned long long v) const {
if (str.flags() & std::ios_base::basefield) {
return this->std::num_put<char>::do_put(out, str, fill, original);
}
if (str.flags() & std::ios_base::showbase) {
*out++ = '0';
*out++ = str.flags() & std::ios_base::uppercase? 'B': 'b';
}
unsigned long long mask(1ull << (std::numeric_limits<unsigned long long>::digits - 1));
while (mask && !(mask & v)) {
mask >>= 1;
}
if (mask) {
for (; mask; mask >>= 1) {
*out++ = v & mask? '1': '0';
}
}
else {
*out++ = '0';
}
return out;
}
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long v) const {
return common_put(out, str, fill, v, static_cast<unsigned long>(v));
}
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long long v) const {
return common_put(out, str, fill, v, static_cast<unsigned long long>(v));
}
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long v) const {
return common_put(out, str, fill, v, v);
}
iter_type do_put(iter_type out, std::ios_base& str, char_type fill, unsigned long long v) const {
return common_put(out, str, fill, v, v);
}
};
std::ostream& bin(std::ostream& out) {
auto const& facet = std::use_facet<std::num_get<char>>(out.getloc());
if (!dynamic_cast<binary_num_put const*>(&facet)) {
std::locale loc(std::locale(), new binary_num_put);
out.imbue(loc);
}
out.setf(std::ios_base::fmtflags(), std::ios_base::basefield);
return out;
}
int main()
{
std::cout << std::showbase << bin << 12345 << " "
<< std::dec << 12345 << "\n";
}
Возможно, просто забыл/никто не нашел времени, чтобы написать и защитить бумагу. – MikeMB
Печатные номера в двоичном формате используются не очень часто. – alain
@alain же для восьмеричного ... Я думаю, – alexolut