Ste*_*ven 6 c++ scope diagnostics c++20
我正在将诊断库中的一些非常旧的代码刷新为现代 C++,但仍然有一段代码一直困扰着我。这是一种非常常见的作用域日志记录函数,它使用宏来定义应用程序特定槽中日志记录数据的存储,这里简化为 int,并带有一个可选版本,该版本采用一个条件来决定是否计时应该发生(例如,对于特定情况,例如第一次通过循环,或者在极端的人工外部计时压力下)。
class ScopedTimer
{
int mSlot;
bool mCondition;
Ticker mBeginTimer;
public:
ScopedTimer( int slot, bool condition ) :
mSlot( slot ),
mCondition(condition)
{
if ( mCondition ) mBeginTimer = GetTimer();
}
~ScopedTimer()
{
if (mCondition)
{
StoreInSlot( mSlot, GetTimer() - mBeginTimer );
}
}
};
#ifdef PROFILING_ENABLED
#define ST_NAME_CONCAT( x, y ) x ## _ ## y
#define ST_NAME_EVALUATOR( x, y ) ST_NAME_CONCAT( x, y )
#define ST_NAME( prefix ) ST_NAME_EVALUATOR( prefix, __LINE__ )
#define SCOPED_TIMER(slot) ScopedTimer ST_NAME(scopedTimer)( slot, condition )
#else
#define SCOPED_TIMER(slot) // goes away in release
#endif
Run Code Online (Sandbox Code Playgroud)
并在使用中:
extern bool ConditionRequestsTiming();
void foo()
{
SCOPED_TIMER( some_magic_slot_number, ConditionRequestsTiming() );
... other operations
}
Run Code Online (Sandbox Code Playgroud)
扩展到
void foo()
{
ScopedTimer scopedTimer12( some_magic_slot_number, ConditionRequestsTiming() );
... other operations
// calling ~ScopedTimer() here, but only if ConditionRequestsTiming was true, storing time difference in the slot
}
Run Code Online (Sandbox Code Playgroud)
并在发布中:
void foo()
{
... other operations
}
Run Code Online (Sandbox Code Playgroud)
这当然可以按预期工作,为该方法提供一个作用域计时器。它非常方便,而且不易出错,但它不尊重命名空间,这一直困扰着我。
对于没有太多复杂性的现代解决方案有什么想法,或者我应该接受这种模式对于我们的诊断库来说是可以的吗?
通常人们使用宏附加__LINE__到声明中,以允许在一个作用域块中进行多个声明。
在 C++20 之前,如果没有宏,这是不可能的。C++20 及更高版本,只需做一点工作,就可以使用std::source_location.
Jason Turner 在他的 C++ 每周视频系列中有一个关于它的视频