如何解决有什么方法可以避免为这个 C++ 范围的记录器使用宏?
我正在将诊断库中的一些非常旧的代码更新为现代 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
并在使用中:
extern bool ConditionRequestsTiming();
void foo()
{
SCOPED_TIMER( some_magic_slot_number,ConditionRequestsTiming() );
... other operations
}
扩展到
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
}
并在发布中:
void foo()
{
... other operations
}
当然可以按预期工作,为该方法提供一个作用域计时器。它非常方便,而且不易出错,但它不尊重命名空间,这一直困扰着我。
关于没有太多复杂性的现代解决方案的任何想法,或者我应该接受这种模式对我们的诊断库来说是否合适?
解决方法
通常人们使用宏将 __LINE__
附加到声明中,以允许在一个作用域块中进行多个声明。
在 C++20 之前,如果没有宏,这是不可能的。 C++20 及更高版本,只需稍加工作,即可使用 std::source_location
。
Jason Turner 在他的 C++ 每周视频系列 here
中有一个关于它的视频 ,除了隐藏计时器实例名称(并导致可能的冲突)之外,我最初不确定是否掌握了该宏的优势。 但我认为目的可能是有可能做到这一点:
#ifdef _DEBUG
#define SCOPED_TIMER(slot) ScopedTimer __scopedTimer( slot );
#else
#define SCOPED_TIMER(slot) ;
#endif
这确实会节省一些按键;否则,如果时间也在发布版本中发生,我将直接使用宏定义;无论哪种方式,我都会去掉对象名称中的初始下划线(通常为编译器实现者保留):
ScopedTimer scoped_timer( some_magic_slot_number );
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。