如何深度复制boost::log::sources::severity_channel_logger_mt对象?需创建带指定通道且继承源日志器所有属性的新实例
如何深度复制boost::log::sources::severity_channel_logger_mt并指定新通道
你遇到的问题很典型:Boost Log 1.66版本里,直接用现有构造方式要么没法继承原日志器的属性,要么修改新日志器的通道会影响原实例。我来给你捋清楚问题根源,再给出可靠的解决方案。
先分析你现有代码的问题
方法一:带通道参数的构造函数
Logger l0 {orig, keywords::channel = "L0"};这个构造函数不会修改原日志器,但它的设计逻辑是复用原日志器的核心配置(比如关联的sink、过滤规则),不会自动复制原日志器的自定义属性(比如你添加的
tid属性不会被l0继承)。方法二:拷贝构造后修改通道
Logger l1 {orig}; l1.channel("L1");拷贝构造出来的
l1会共享原日志器的属性容器,调用channel()方法修改的是共享的通道属性,所以会意外修改原日志器orig的通道值,这显然不是你想要的。
正确的深度复制方案
要实现「继承所有属性+独立新通道+不影响原日志器」,需要手动复制原日志器的所有属性,并确保新日志器拥有独立的属性集合。具体步骤如下:
- 创建一个指定新通道的新日志器实例;
- 遍历原日志器的所有属性,逐个克隆并添加到新日志器中(
clone()方法会创建属性的独立副本,避免共享); - 按需添加新属性或修改配置,完全不会影响原日志器。
完整代码示例
using namespace boost::log; using Logger = sources::severity_channel_logger_mt<trivial::severity_level, std::string>; int main() { // 原日志器 Logger orig {keywords::channel = "LL"}; orig.add_attribute("tid", attributes::constant<std::string>("TT")); // 1. 创建带新通道的新日志器 Logger cloned_logger {keywords::channel = "NewChannel"}; // 2. 深度复制原日志器的所有属性 auto orig_attributes = orig.attribute_values(); for (const auto& attr_pair : orig_attributes) { // 使用clone()创建属性的独立副本,避免与原日志器共享 cloned_logger.add_attribute(attr_pair.first, attr_pair.second.clone()); } // 3. 测试:修改新日志器的属性和通道,不会影响原日志器 cloned_logger.add_attribute("attr", attributes::constant<std::string>("0A")); cloned_logger.channel("UpdatedNewChannel"); // 验证原日志器状态未变 BOOST_LOG(orig) << "原日志器通道:" << orig.channel(); // 输出 "LL" BOOST_LOG(orig) << "原日志器tid属性:" << orig.attribute_values()["tid"].extract<std::string>(); // 输出 "TT" return 0; }
封装成工具函数(可选)
如果需要频繁复制日志器,可以封装一个通用函数,方便复用:
template<typename LoggerType> LoggerType deep_copy_logger_with_channel(const LoggerType& source_logger, const typename LoggerType::channel_type& new_channel) { // 创建带新通道的日志器 LoggerType new_logger(boost::log::keywords::channel = new_channel); // 复制所有属性 auto source_attrs = source_logger.attribute_values(); for (const auto& attr : source_attrs) { new_logger.add_attribute(attr.first, attr.second.clone()); } // 可选:复制过滤规则、关联的sink等其他配置 new_logger.set_filter(source_logger.filter()); new_logger.add_sinks(source_logger.sinks()); return new_logger; }
调用方式非常简单:
Logger cloned_logger = deep_copy_logger_with_channel(orig, "MyNewChannel");
内容的提问来源于stack exchange,提问作者sba
相关产品推荐
相关产品推荐

