我写了一个Logger
类,用于将信息转储到文件中。以下代码是Logger
的缩影。功能看起来几乎相同......但我不知道如何简化它。你能让它更优雅吗?
My earlier version使用了varadic宏来实现这一目标。后来我注意到这两个数据,文件指针和缩进级别可以封装到一个类中,因此我不需要每次都传递(FILE *fp, size_t indent)
。 (Xml_Logger &logger)
就够了。
所以我希望我可以使用会员功能,否则就像我回滚......
void ind_print(const char *format, ...) {
print_indent();
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void ind_println(const char *format, ...) {
print_indent();
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
}
void print(const char *format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void println(const char *format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
printf("\n");
}
更新:看看这两个功能。我希望println
可以调用print
,但遗憾的是它不能。不是吗?
void Xml_Logger::print(const char *format, ...) const {
print_indent();
va_list args;
va_start(args, format);
vfprintf(fp, format, args);
va_end(args);
}
void Xml_Logger::println(const char *format, ...) const {
print_indent();
va_list args;
va_start(args, format);
vfprintf(fp, format, args);
va_end(args);
fputc('\n', fp);
}
答案 0 :(得分:1)
我会写类似的东西(是的,也是使用宏):
print.h:
void _print(int indent, int eol, const char *format, ...);
#define print(format, ...) _print(0, 0, format, __VA_ARGS__)
#define println(format, ...) _print(0, 1, format, __VA_ARGS__)
#define ind_print(format, ...) _print(1, 0, format, __VA_ARGS__)
#define ind_println(format, ...) _print(1, 1, format, __VA_ARGS__)
print.c:
void _print(int indent, int eol, const char *format, ...) {
va_list args;
if (ident) {
print_indent();
}
va_start(args, format);
vprintf(format, args);
va_end(args);
if (eol) {
printf("\n");
}
}
答案 1 :(得分:1)
就像你没有将你的论点转发给fprintf
,这是变量,但vfprintf
,你会在你的情况下做同样的事。
void Xml_Logger::master_print(bool indent, bool newline, const char* format, va_list& args) const
{
if (indent) print_indent();
vfprintf(fp, format, args);
if (newline) fputc('\n', fp);
}
void Xml_Logger::print(const char *format, ...) const
{
va_list args;
va_start(args, format);
master_print(true, false, format, args);
va_end(args);
}
void Xml_Logger::println(const char *format, ...) const
{
va_list args;
va_start(args, format);
master_printf(true, true, format, args);
va_end(args);
}
但不幸的是,这需要在每个包装器中重复va_list
个东西。因此,如果你有C ++ 11,请尝试使用a template with perfect forwarding
答案 2 :(得分:0)
您可以将这些功能减少为可变宏,这样您就可以摆脱对va_start
和va_end
的多余调用:
#define IND_PRINT(fmt, ...) { \
print_indent(); \
printf(fmt, ## __VA_ARGS__); \
}
然后你应该将每个宏放在一个头文件中,这样它们对项目的其余部分都是可见的。
答案 3 :(得分:0)
您可以使用C ++ 11可变参数模板转发可变数量的参数:
template<typename ...TArgs>
void Xml_Logger::println(const char *format, TArgs&& ...args) const
{
print(format, std::forward(args)...);
fputc('\n', fp);
}