It’s best to make the interface as simple as possible. Separate the registration user interface completely from how registration is actually performed.
Cross-cutting issues are always expensive to maintain, so making things harder will make you hate life.
Some library just wants something simple:
void logDebug(const std::string &msg);
void logWarning(const std::string &msg);
void logError(const std::string &msg);
They should not add or indicate any other context. In any case, no one can use this information, so you should not design it.
, , . , . , , .
, ( , ) , .
UPDATE:
, . , , , .
. , .
, X Y . , , . , - , .
, (, ). , . - , . , , .
void setLoggingContext("X:");
, RAII .
LoggingTag tag("X:");
, , . , , .
void foo() {
LoggingTag tag("X:");
logWarning("foo");
bar();
baz();
}
void bar() {
LoggingTag tag("Y:");
logWarning("bar");
baz();
}
void baz() {
logWarning("baz");
}
, . baz LoggingTag. , logWarning .
- , - .
struct LoggingTag {
LoggingTag(const std::string &tag_) : tag(tag_) {}
template<typename T>
static LoggingTag ByType() {
return LoggingTag(typeid(T).name());
}
std::string tag;
};
void foo() {
LoggingTag tag = LogginTag::ByType<int>();
}
- typeid(T).name(), , .