为什么std::num_put通过非常量引用获取ios_base参数

Why does std::num_put take the ios_base parameter by non-const reference?

本文关键字:引用 获取 ios base 参数 常量 num std put 为什么 非常      更新时间:2023-10-16

我正在尝试iostreams/locale数字方面,我发现了一些非常奇怪的东西:

使用std::num_put方面直接格式化数字的"规范示例"如下:

std::string f(double value) {
    using namespace std;
    stringstream ss;
    num_put<char> const& npf = use_facet<num_put<char> >(ss.getloc());
    npf.put(/*out=*/ss, /*format=*/ss, /*fill=*/' ', value);
    return ss.str();
}

put第一个参数是写入输出的对象。

我们也可以有这样的代码,它可以工作:

std::string g(double value) {
    using namespace std;
    stringstream ss;
    typedef char* CharBufOutIt;
    num_put<char, CharBufOutIt> const& npf = use_facet<num_put<char, CharBufOutIt> >(ss.getloc());
    char big_enough_buf[100];
    npf.put(/*out=*/big_enough_buf, /*format=*/ss, /*fill=*/' ', value);
    return big_enough_buf;
}

put()第二个参数是一个流对象,用于确定要应用的特定格式。第二个参数是,根本没有修改。(在我的实现中没有,也没有根据文档描述的这个参数的用途。)

然而,put的签名看起来是这样的:

iter_type put(iter_type out,std::ios_base&str,char_type-fill,long双v)const;

也就是说,它通过非常量引用获取ios_base对象,即使它看起来确实应该通过常量引用获取。

我是不是错过了什么?这只是C++iostreams规范中的一个(历史?)特性吗?C++标准委员会讨论过这个问题吗?

根据标准(22.4.2.2.2),put的实施在一点上是这样的:

第3阶段:

如果str.width()为非零,并且阶段2之后的序列中的charT’s的数量小于str.width(),则在指示用于填充的位置处将足够的填充字符添加到序列,以使序列的长度达到str.width()。调用str.width(0)

此外,str.width(0)调用未声明constwidth(请参阅此链接):

streamsize ios_base::width (streamsize wide);