我有一个想法,用 C++ 创建一些 Python 记录器。关键是可以创建具有嵌套名称的子代。
我写了这样的东西(简化的例子):
#include <iostream>
// Some third-party logger that I can't change
struct LogImpl {
std::function<std::string(const std::string &msg)> formatter{nullptr};
void write(const std::string &msg) const {
const auto fMsg = formatter ? formatter(msg) : msg;
std::cerr << fMsg << std::endl;
}
};
// My wrapper
struct Logger {
std::string name;
LogImpl *impl{nullptr};
explicit Logger(const std::string &name, LogImpl *impl) : name(name), impl(impl) {}
std::shared_ptr<Logger> getChild(const std::string &name_) const {
return std::make_shared<Logger>(name + "." + name_, impl);
}
void write(const std::string &msg) const {
impl->write(msg);
}
void setRichFormat() const {
impl->formatter = [&](const std::string &msg) {
return name + "\t" + msg + "\n";
};
}
};
int main() {
auto impl = new LogImpl();
Logger rootLogger{"root", impl};
auto childLogger = rootLogger.getChild("child");
rootLogger.setRichFormat();
rootLogger.write("ROOT MSG");
childLogger->write("CHILD MSG");
delete impl;
return 0;
}
但很明显,在这种情况下输出将是:
root ROOT MSG
root CHILD MSG
我想如何更改此代码以达到结果:
root ROOT MSG
root.child CHILD MSG
我无法发明一些东西来解决这个问题。
在我看来这有点夸张了。 为什么不简单地:
struct Logger {
std::string name;
explicit Logger(const std::string &name) : name(name) {}
void write(const std::string &msg) const {
std::cerr << name << "\t" << msg << "\n";
}
};
int main() {
Logger rootLogger{"root"};
Logger childLogger{"root.child"};
rootLogger.write("ROOT MSG");
childLogger.write("CHILD MSG");
}