我想利用类构造函数和解构函数来通过RAII成语在我的日志文件中表示和格式化作用域。使用单个#define
,它会打印“{”并增加全局缩进级别,以便下一个记录行将在该缩进级别打印。防止解构宏定义的匿名变量,直到范围结束
LogScopeRAII
应该打印“}”并自然减少全局缩进级别,因为它在Foo()
的末尾超出了范围。但是,我所看到的行为是LogScopeRAII在构建后立即被解构。
假设:我认为这个问题是一个正在上分配的RHS创建LogScopeRAII(因而匿名?),并在该行的末尾被销毁,但我不知道该怎么办关于。我认为LOG_ANONYMOUS_VARIABLE
在VSCOPE_F
会做到这一点,并导致它坚持下去,但事实并非如此。
问题:如何阻止LogScopeRAII被解构,直到调用函数超出范围?
/* Header */
LogScopeRAII::LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, const char* format, ...)
{
// ...
// print "{" and then increase an indentation global var
}
LogScopeRAII::~LogScopeRAII()
{
// ...
// print "}" and then decrease the indentation global var
}
#define LOG_ANOMYMOUS_VARIABLE(str) LOG_CONCAT(str, __LINE__)
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
#define SCOPE_F(verbosity_name, ...) VSCOPE_F(Verbosity_ ## verbosity_name, __VA_ARGS__)
#define SCOPE_FUNCTION(INFO) SCOPE_F(verbosity_name, __FUNCTION__)
/* Implementation */
void Foo()
{
SCOPE_FUNCTION(INFO) // print "{" and increase indentation
for (size_t i = 0; i < 3; ++i)
{
// do work
LOG(INFO, "Work logged");
}
// print "}" and decrease indentation
}
希望的输出:
{ Foo()
"Work Logged" // Note indentation
} 0.23 s: Foo()
编辑:煮ISSUE DOWN
的它的关键是这样的:所述三元似乎并不奏效。
这工作:
LogScopeRAII a(LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
但这并不:
LogScopeRAII a(((Verbosity_INFO) > indent) ? LogScopeRAII() : LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
我得到:
{
}
Work logged
Work logged
Work logged
}
constructCounter: 1
destructCounter: 2
Exiting...
馅这个在这一点上宏是有点为时过早。在实际的代码中分解出来,按照你想要的方式工作,然后根据需要添加宏。 –
请参阅编辑。接受你的建议。似乎三元不工作? – Stradigos
也许LogScopeRAII的移动结构被打破。 “工作版本”将隐藏由于复制影响而导致的问题,但是没有使用条件运算符版本的副本。至少需要在析构函数中有代码才能发出'}',如果这是一个已经被移出的临时文件等。 –