You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让std::chrono::duration的单位可配置?求简便实现方案

问题描述

我想通过boost::property_tree解析的XML配置文件,设置std::chrono::duration的输出单位。尝试用std::variant实现但代码编译失败,我不擅长元编程,有没有更简单的实现方式?本质上我能确定duration类型只会是指定的子集(秒、毫秒、微秒、纳秒)。

原尝试代码

头文件类声明

using TimestampVariant = std::variant<
        std::chrono::nanoseconds, 
        std::chrono::microseconds,
        std::chrono::milliseconds,
        std::chrono::seconds
    >; 

TimestampVariant _timestamp_v;

cpp文件实现

auto GetTimestampVisitor =  [](const auto& t) -> decltype(auto) {
    return std::chrono::duration_cast<std::remove_reference_t<decltype(t)>>(std::chrono::system_clock::now().time_since_epoch()).count(); 
};

void SetupFunction()
{
    boost::property_tree::ptree property_tree;
    boost::property_tree::read_xml(filepath, property_tree);
    auto config = property_tree.get_child("Config");
    std::string timestamp_type = config.get<std::string>("ReportingUnits");
    if(!timestamp_type.compare("seconds") || !timestamp_type.compare("s"))
    {
        _timestamp_v = std::chrono::seconds();
    }
    else if(!timestamp_type.compare("milliseconds") || !timestamp_type.compare("ms"))
    {
        _timestamp_v = std::chrono::milliseconds();
    }
    else if(!timestamp_type.compare("microseconds") || !timestamp_type.compare("us"))
    {
        _timestamp_v = std::chrono::microseconds();
    }
    else if(!timestamp_type.compare("nanoseconds") || !timestamp_type.compare("ns"))
    {
        _timestamp_v = std::chrono::nanoseconds();
    }
}

void OutputFunction()
{
   std::cout << std::visit(GetTimestampVisitor, _timestamp_v) << std::endl;
}

更简单的实现方案

不用std::variant和访问者模式,改用枚举存储时间单位,输出时通过switch分支处理,代码更直观且无元编程复杂度:

步骤1:定义时间单位枚举

在类中添加枚举类型,替代variant成员:

enum class TimestampUnit {
    Seconds,
    Milliseconds,
    Microseconds,
    Nanoseconds
};

TimestampUnit _timestamp_unit = TimestampUnit::Nanoseconds; // 设置默认单位

步骤2:修改配置解析逻辑

解析XML时直接设置枚举值:

void SetupFunction()
{
    boost::property_tree::ptree property_tree;
    boost::property_tree::read_xml(filepath, property_tree);
    auto config = property_tree.get_child("Config");
    std::string timestamp_type = config.get<std::string>("ReportingUnits");
    
    if (timestamp_type == "seconds" || timestamp_type == "s")
    {
        _timestamp_unit = TimestampUnit::Seconds;
    }
    else if (timestamp_type == "milliseconds" || timestamp_type == "ms")
    {
        _timestamp_unit = TimestampUnit::Milliseconds;
    }
    else if (timestamp_type == "microseconds" || timestamp_type == "us")
    {
        _timestamp_unit = TimestampUnit::Microseconds;
    }
    else if (timestamp_type == "nanoseconds" || timestamp_type == "ns")
    {
        _timestamp_unit = TimestampUnit::Nanoseconds;
    }
    // 可选:添加else分支处理无效配置,比如报错或保持默认值
}

步骤3:修改输出逻辑

通过switch分支根据枚举值执行对应的duration转换:

void OutputFunction()
{
    auto epoch_duration = std::chrono::system_clock::now().time_since_epoch();
    switch (_timestamp_unit)
    {
        case TimestampUnit::Seconds:
            std::cout << std::chrono::duration_cast<std::chrono::seconds>(epoch_duration).count() << std::endl;
            break;
        case TimestampUnit::Milliseconds:
            std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(epoch_duration).count() << std::endl;
            break;
        case TimestampUnit::Microseconds:
            std::cout << std::chrono::duration_cast<std::chrono::microseconds>(epoch_duration).count() << std::endl;
            break;
        case TimestampUnit::Nanoseconds:
            std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(epoch_duration).count() << std::endl;
            break;
    }
}

原代码编译失败原因

原代码中std::visit要求访问者的所有重载返回类型必须一致,但不同std::chrono::duration的count()返回值类型可能存在差异(比如部分编译器下不同单位的rep类型不同),导致编译报错。而枚举方案完全规避了这个问题,同时代码逻辑更易读。

内容的提问来源于stack exchange,提问作者SeedlessKiwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:45:00