c++ - 如何将 "add"用户自定义格式标志转为 basic_ostream?

标签 c++

我想提供一个流运算符来输出 std::chrono::time_point 作为 GMT 日期,我目前有以下内容(仅针对 ostream 进行了简化):

using datetime_t = std::chrono::system_clock::time_point;

std::ostream& operator<<(std::ostream &out, datetime_t dt) {
    auto time = datetime_t::clock::to_time_t(dt);
    auto under_sec = 
        std::chrono::duration_cast<std::chrono::milliseconds>(
            dt.time_since_epoch() % std::chrono::seconds{1});
    return out << std::put_time(std::gmtime(&time), "%Y-%m-%dT:%H:%M:%S")
               << "." << std::setfill('0') << std::setw(3) << under_sec.count();
}

用法:

auto time = datetime_t::clock::now();
std::cout << time;

这有效,但它迫使用户:

  • 使用硬编码格式;
  • 输出毫秒。

我想提供自定义流操纵器,允许用户修改这两个,例如对于第二个(假设命名空间 nm 包含操纵器):

std::cout << nm::us << time;

...这将打印到微秒。

我已经知道如何创建流操纵器,例如:

namespace nm {
    std::ios_base& us(std::ios_base &) { /* ... */ }
}

...但我不知道如何“存储”在输出运算符中使用所需的信息。

有没有一种简单的方法可以将信息“存储”在流中(用户定义的格式标志?)以供以后的流操作使用?或者另一种获得稍微等效行为的方法?

最佳答案

正如您已经在评论中发现的那样,是的,流具有 iwordpword 存储空间。这不是世界上最容易使用的东西(设计几十年了),但可以维修。

另一种选择是为此使用已经编码的库,例如 Howard Hinnant's free, open source, datetime library :

#include "date.h"
#include <iostream>

int
main()
{  
    using namespace date;
    using namespace std::chrono;
    std::cout << format("%FT:%T", floor<microseconds>(system_clock::now())) << '\n';
}

有了这个库,输出的精度是通过调整输入的精度来控制的(即使用 time_point_castfloor)。

示例输出:

2017-07-10T:11:46:59.354321

关于c++ - 如何将 "add"用户自定义格式标志转为 basic_ostream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45008434/

相关文章:

c++ - 连续内存、OpenGL,以及如何包装顶点?

c++ - 如何将 -fix 选项添加到 .clang-tidy 文件?

c++ - 为什么 "cin >>"作为条件

c++ - constexpr 唯一标识,使用 clang 编译但不使用 gcc

c++ - Qtimer不超时QT,C++

C++ system() 调用未正确记录 Java 返回码

c++ - 如何在不导致像素重叠的情况下缩小块

c++ - 正确关闭boost线程

c++ - 使用 Cygwin 编译 C++ 项目

c++ - 两个代码段之间执行时间的奇怪差异