我们正在使用一个第三方的C库,该库提供了一个类似于printf()
的日志函数。
void log(const char *format, ...);
出于一些不必细说的原因,我们需要限制消息记录的速率,大致如下:
void rate_limited_log(const char* format, ...)
{
if (<not too fast>) {
log(format, ...);
}
}
幸运的是,C库的作者知道他们在做什么,并提供了
void logv(const char* format, va_list ap);
所以编写上述函数是相对简单的事情。不幸的是,可变参数函数与内联不兼容,因此我想出了第二个解决方案:
template <typename... T>
void rate_limited_log(const char* format, T&&... args)
{
if (<not too fast>) {
log(format, std::forward<T>(args)...);
}
}
这个代码完美运行并且内联了我们想要的速率限制条件。但是我有一些疑问:
在C++11中,将参数包扩展到类似C风格的可变参数函数调用中是否合法和定义良好?或者我们只是走了运,它恰好起作用了?
既然我们正在调用一个C函数,那么这里的
&&
和std::forward
是否真的必要?如果我使用const T&
,甚至只是按值传递T
,都可以正常工作,无论是否使用std::forward
。
__FILE__
和__LINE__
到内部函数中,因为调试宏生成的代码通常很痛苦。在宏中执行必要的操作(有时候像字符串连接这样的操作可以更快),而其他所有操作都在普通的代码中执行(PS:你需要在上面添加一些\
)。 - Yakk - Adam Nevraumont