防止解构宏中定义的匿名变量直到范围结束
Preventing deconstruction of anonymous variable defined in macro until end of scope
我正在尝试利用 class 构造函数和解构函数通过 RAII 习惯用法来表示和格式化我的日志文件中的范围。使用单个 #define
,它打印“{”并增加全局缩进级别,以便在该缩进级别打印下一个记录行。
LogScopeRAII
应该打印“}”并自然降低全局缩进级别,因为它在 Foo()
结束时超出范围。但是,我看到的行为是 LogScopeRAII 在构造后立即被解构。
假设:我认为问题是 LogScopeRAII 是在赋值的 RHS 上创建的(因此是匿名的?)并在行尾被销毁,但我不知道该怎么办。我以为 VSCOPE_F
中的 LOG_ANONYMOUS_VARIABLE
会成功并让它一直存在,但事实并非如此。
问题:如何在调用函数超出范围之前阻止 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()
编辑:解决问题
症结在于:三元组似乎不起作用。
这个有效:
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...
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
应该是
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) \
(((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__})
否则你使用临时变量的拷贝构造函数。
(您也可以修复移动构造函数和析构函数以允许当前的 MACRO)
我正在尝试利用 class 构造函数和解构函数通过 RAII 习惯用法来表示和格式化我的日志文件中的范围。使用单个 #define
,它打印“{”并增加全局缩进级别,以便在该缩进级别打印下一个记录行。
LogScopeRAII
应该打印“}”并自然降低全局缩进级别,因为它在 Foo()
结束时超出范围。但是,我看到的行为是 LogScopeRAII 在构造后立即被解构。
假设:我认为问题是 LogScopeRAII 是在赋值的 RHS 上创建的(因此是匿名的?)并在行尾被销毁,但我不知道该怎么办。我以为 VSCOPE_F
中的 LOG_ANONYMOUS_VARIABLE
会成功并让它一直存在,但事实并非如此。
问题:如何在调用函数超出范围之前阻止 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()
编辑:解决问题
症结在于:三元组似乎不起作用。
这个有效:
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...
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
应该是
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) \
(((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__})
否则你使用临时变量的拷贝构造函数。
(您也可以修复移动构造函数和析构函数以允许当前的 MACRO)