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

时间:2013-12-04 16:10:10

标签: c++ formatting iostream facet const-correctness

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

使用std::num_put facet直接格式化数字的“规范示例”如下:

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()是一个流对象,用于确定要应用的特定格式。第二个参数是未修改。 (不在我的实现中,而不是根据the docs describe此参数的用途。)

然而,put的签名如下所示:

  

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

也就是说,它是通过非const 引用来获取ios_base对象,即使它出现了它应该通过 const 引用来实现它。

我错过了什么吗?这只是C ++ iostreams规范中的(历史?)特性吗?这个曾经被C ++ std委员会讨论过吗?

1 个答案:

答案 0 :(得分:2)

Standard(22.4.2.2.2)开始put的实施就是这样:

  

第3阶段:

     

如果str.width()非零并且第2阶段后序列中charT’s的数量小于str.width(),那么在指定用于填充的位置处的序列中会添加足够的填充字符将序列的长度调到str.width()str.width(0)被称为。

此外,str.width(0)在没有width的情况下调用const(请参阅this link):

streamsize ios_base::width (streamsize wide);