Я пытаюсь использовать конструкторы классов и деконструкторы для представления и форматирования области в моих файлах журналов с помощью идиомы RAII. Используя один #define
, он печатает «{» и увеличивает глобальный уровень отступов, чтобы следующая строка журнала была напечатана на этом уровне отступов.Предотвращение деконструкции анонимной переменной, определенной в макросе до конца области
LogScopeRAII
Предполагается напечатать "}" и естественно уменьшить глобальный уровень отступа, поскольку он выходит за пределы области действия в конце Foo()
. Однако поведение, которое я вижу, заключается в том, что LogScopeRAII деконструируется сразу после его построения.
Гипотезы: Я думаю, что проблема в том, что 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()
EDIT: ВАРЕНЬЕ ПРОБЛЕМУ ВНИЗ
Суть его заключается в следующем: не похоже, работает тройная.
Это работает:
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 нарушена. «Рабочая версия» скроет проблему из-за копирования, но нет копии с условной версией оператора. По крайней мере, в деструкторе должен быть код, чтобы не испускать '}', если это временное, которое было перемещено из и т. Д. –