有什么办法可以避免对这个 C++ 作用域记录器使用宏?

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)

这当然可以按预期工作,为该方法提供一个作用域计时器。它非常方便,而且不易出错,但它不尊重命名空间,这一直困扰着我。

对于没有太多复杂性的现代解决方案有什么想法,或者我应该接受这种模式对于我们的诊断库来说是可以的吗?

Cas*_*sey 6

通常人们使用宏附加__LINE__到声明中,以允许在一个作用域块中进行多个声明。

在 C++20 之前,如果没有宏,这是不可能的。C++20 及更高版本,只需做一点工作,就可以使用std::source_location.

Jason Turner 在他的 C++ 每周视频系列中有一个关于它的视频