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

如何用boost::property_tree读取XML中的无限时长配置?

实现支持无限/有限时长的boost::property_tree读取方案

方法一:先读取字符串再判断(简单直接)

先读取字段的原始字符串,再根据内容判断是无限时长还是有限时长,适合快速实现:

boost::property_tree::ptree property_tree;
boost::property_tree::read_xml(filepath, property_tree);
auto config = property_tree.get_child("Config");

std::string duration_str = config.get<std::string>("MyDurationField");
std::chrono::seconds my_duration_value;
bool is_infinite = false;

// 兼容大小写的"inf"判断
if (duration_str == "inf" || duration_str == "INF") {
    is_infinite = true;
    // 用chrono秒的最大值标记无限时长,可根据业务需求替换
    my_duration_value = std::chrono::seconds::max();
} else {
    try {
        // 转换为unsigned int后转成秒,处理非法输入
        unsigned int sec = std::stoul(duration_str);
        my_duration_value = std::chrono::seconds(sec);
    } catch (const std::exception& e) {
        throw std::invalid_argument("非法的时长值: " + duration_str);
    }
}

方法二:自定义Property Tree转换器(优雅复用)

通过实现boost::property_tree的自定义转换器,可直接用get方法读取带无限标记的时长,代码更整洁且复用性强:

定义转换器

#include <boost/property_tree/ptree.hpp>
#include <chrono>
#include <string>
#include <stdexcept>

struct DurationTranslator {
    using internal_type = std::string;
    using external_type = std::chrono::seconds;

    // 从字符串转换为时长,支持"inf"
    boost::optional<external_type> get_value(const internal_type& str) {
        if (str == "inf" || str == "INF") {
            return boost::make_optional(external_type::max());
        }
        try {
            unsigned int sec = std::stoul(str);
            return boost::make_optional(external_type(sec));
        } catch (...) {
            return boost::none; // 转换失败返回空,触发property_tree异常
        }
    }

    // 反向转换(如需将时长写回XML时使用)
    boost::optional<internal_type> put_value(const external_type& dur) {
        if (dur == external_type::max()) {
            return boost::make_optional(std::string("inf"));
        } else {
            return boost::make_optional(std::to_string(dur.count()));
        }
    }
};

使用转换器读取值

boost::property_tree::ptree property_tree;
boost::property_tree::read_xml(filepath, property_tree);
auto config = property_tree.get_child("Config");

// 用自定义转换器读取时长
std::chrono::seconds my_duration_value = config.get<std::chrono::seconds>(
    "MyDurationField",
    DurationTranslator()
);

// 判断是否为无限时长
bool is_infinite = (my_duration_value == std::chrono::seconds::max());

补充:用std::optional标记无限时长

如果业务中可能用到接近seconds::max()的时长,可改用std::optional标记无限,避免冲突:

定义可选时长转换器

struct OptionalDurationTranslator {
    using internal_type = std::string;
    using external_type = std::optional<std::chrono::seconds>;

    boost::optional<external_type> get_value(const internal_type& str) {
        if (str == "inf" || str == "INF") {
            return boost::make_optional(external_type(std::nullopt));
        }
        try {
            unsigned int sec = std::stoul(str);
            return boost::make_optional(external_type(std::chrono::seconds(sec)));
        } catch (...) {
            return boost::none;
        }
    }

    boost::optional<internal_type> put_value(const external_type& dur) {
        if (!dur.has_value()) {
            return boost::make_optional(std::string("inf"));
        } else {
            return boost::make_optional(std::to_string(dur->count()));
        }
    }
};

使用示例

std::optional<std::chrono::seconds> my_duration_value = config.get<std::optional<std::chrono::seconds>>(
    "MyDurationField",
    OptionalDurationTranslator()
);

if (!my_duration_value) {
    // 处理无限时长逻辑
} else {
    // 处理有限时长逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:33:24