是否有建议将std :: bin添加到c ++标准? [英] Has there been a proposal to add std::bin to the c++ standard?

查看:123
本文介绍了是否有建议将std :: bin添加到c ++标准?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 14通过为值输入0b前缀来增加使用二进制文字的能力:

C++14 adds ability to use binary literals by typing 0b prefix for the value:

int v = 0b1111; // 15 in decimal

但是没有像std::hexstd::oct这样的流的std::bin操纵器.所以我需要使用std::bitset用于打印:

But there is no std::bin manipulator for streams like std::hex or std::oct. So I need to use e.g. std::bitset for printing purpose:

std::cout << std::bitset<4>(v) << "\n";

是否已提出或考虑了?如果是这样,这个想法的现状如何?

Has it been proposed or considered? If so, what's the status of the idea?

推荐答案

据我所知,没有提交任何提案来添加格式标志来添加二进制格式和/或操纵器std::bin.您可以在 http://www.open-std中查看建议. org/jtc1/sc22/wg21/docs/papers/.我非常确定添加二进制文字的建议不会添加此功能(快速搜索显示

As far as I know there was no proposal submitted to add a formatting flag to add binary formatting and/or a manipulator std::bin. You can check the proposals at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/. I'm pretty sure the proposal to add binary literals did not add this facility (a quick search revealed N3472 but I'm not sure if this is the latest version of the paper).

从技术角度看,添加它可能并不完全容易!通常,各种标志都全部存储在流类中的一个字中,并且出于各种原因耗尽所有位.现有的三个设置(std::ios_base::octstd::ios_base::decstd::ios_base::hex)可以很好地存储在2位中.当然,这三个值将使一个值保持打开状态,只是该值通常用于默认设置,即在读取时不固定基数.结果,可能有必要更改流类的布局或使处理效率降低(例如,通过某种方式使用iword()存储二进制格式的其他可能性).我还没有分析任何实现是否存在实际问题(我知道我的实现没有问题,但是如果我没记错的话,我确实使用了一个单词中的所有位).

From a technical point of view it may not be entirely easy to add! The various flags are normally all stored in just one word in the stream class and there are various reasons to use up all the bits. The existing three settings (std::ios_base::oct, std::ios_base::dec, std::ios_base::hex) can be nicely stored in just 2 bits. Of course, the three values would leave one value open except that this value is typically taken for the default setting, i.e., not fixing the base when reading. As a result it may be necessary to change the layout of the stream classes or to make processing less efficient (e.g., by somehow using an iword() to store the additional possibility of binary formatting). I haven't done the analysis whether there is an actual problem with any of the implementations (I know there is none for my implementation but I did use all the bits in a word if I recall correctly).

如果要支持二进制格式,则通过自定义std::num_put<char>构面添加相对容易.以下是一个简单的示例.它不处理某些可能需要的格式选项,例如填充或数字分隔符:

If you want to support binary formatting it is relatively easy to add via a custom std::num_put<char> facet. Below is a simple example. It doesn't deal with some of the formatting options which may be desirable like padding or digit separators:

#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";
}

这篇关于是否有建议将std :: bin添加到c ++标准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆