【问题标题】:Why does std::num_put take the ios_base parameter by non-const reference?为什么 std::num_put 通过非常量引用获取 ios_base 参数?
【发布时间】:2013-12-21 05:30:05
【问题描述】:

我正在试验 iostreams / locale numeric facet,我遇到了一些非常奇怪的事情:

使用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& str, char_type fill, long 双 v ) 常量;

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

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

【问题讨论】:

  • @0x499602D2 getLoc 带有 const,但是在 vs2013 的实现中,函数 width(0) 被调用,并且该函数是非 const
  • @Raxvan 你能告诉我它在哪里吗?
  • @Raxvan 奇怪。在 cppreference 上没有 const。
  • @0x499602D2 :)),有趣的发现

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


【解决方案1】:

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2020-07-31
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多