问题描述
我想记录一个函数的返回值。问题是,函数可能有很多出口点,我不想在每个人之前添加一个日志调用。
我想到有一个内部对象它负责进行 Log 调用。但仍然,我必须在每个返回语句之前通知它的返回值。
创建一个宏,在从函数返回之前调用记录器。像:
#define RETURN(ret)Logger.log(__ FUNCTION__,ret); return ret;
但我想避免这样做。
感谢
我不认为你可以做得更好,更容易。在这种情况下,我认为对源的影响最小的解决方案是使用预处理器,但是你不应该这样做,因为它已经内置了代价。Fx:
if(done)
RETURN(something);
可扩展为:
if(done)
Logger.log(function_name,something);返回东西
这意味着 something 如果 done 为true,则返回。
为了使扩展适合单个语句,它通常包装在 do {...} while(0),这将使该示例日志, done 为true。
但是仍然有一个惊喜,因为宏参数扩展了两次,考虑你写 RETURN(something ++); 然后它会扩展到 Logger.log(__ FUNCTION__,something ++);返回一些++; 这意味着不幸的副作用。这是C中的一个真正的问题,但不是在C ++。这里的模板很方便:
模板< typename T&
T const& log_and_return(char const * func,const T& value)
{
Logger.log(func,value);
返回值;
}
#define RETURN(value)return log_and_return(__ func__,value)
注意,它在标准中被称为 __ func __ (不 __ FUNCTION __ )。
I would like to log the return value of a function. The problem is that the function might have many exit points and I don't want to add a log call before every one of them.
I thought about having an inner object that's responsible on making the Log call. But still, I would have to notify it about the return value before each return statement.
I also thought about creating a macro that calls the logger before returning from the function. Something like:
#define RETURN(ret) Logger.log(__FUNCTION__, ret); return ret;
But I want to avoid doing that.
Any other thoughts on how I can achieve that nicely and easily?
Thanks
I don't think you can do that more nicely and easily. In this case I think the solution with least impact on the source is to use the preprocessor, but you shouldn't do it the way you do because it has surprices built in. Fx:
if( done ) RETURN(something);
expands to:
if( done ) Logger.log("function_name", something); return something;
which means that something is sent to the log if done is true, then something is returned anyway.
To make the expansion fit into a single statement it's normally wrapped in a do { ... } while(0) which would make that example log and return only if done is true.
But there's still a surprise since the macro argument is expanded twice, consider the case where you write RETURN(something++); then it will expand to Logger.log(__FUNCTION__, something++); return something++; which means unfortunate side effects. This was a real problem in C, but not in C++. Here templates are handy:
template<typename T> T const& log_and_return(char const* func, const T& value) { Logger.log(func, value); return value; } #define RETURN(value) return log_and_return(__func__, value)
Note that it is called __func__ in the standard (an not __FUNCTION__).
这篇关于记录函数的返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!