如何简化这些变进函数
How to simplify these variadic functions?
我编写了一个Logger
类,用于将信息转储到文件中。下面的代码是Logger
的一个缩影。函数看起来几乎是一样的…但我不知道怎么化简。你能让它更优雅吗?
我的早期版本使用可变宏来实现这个目标。后来我注意到这两个数据,文件指针和缩进级别,可以被封装到一个类中,这样我就不需要每次都通过(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);
}
就像你不把你的参数转发给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,试着使用一个有完美转发的模板
我会写这样的东西(是的,也使用宏):
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");
}
}
您可以将这些函数减少为可变宏,这样您就可以摆脱对va_start
和va_end
的冗余调用:
#define IND_PRINT(fmt, ...) {
print_indent();
printf(fmt, ## __VA_ARGS__);
}
然后你应该把这些宏放在一个头文件中,这样它们对你的项目的其余部分是可见的。
您可以使用c++ 11可变模板来转发可变数量的参数:
template<typename ...TArgs>
void Xml_Logger::println(const char *format, TArgs&& ...args) const
{
print(format, std::forward(args)...);
fputc('n', fp);
}
相关文章:
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 简化C++包括变量名称和函数输出的模式
- 简化文件读取的函数
- 简化 if 流函数的 while 循环中的大量 while 循环
- "virtual"对C++析构函数有何影响?
- C++ 友元函数在内存位置上有何不同?
- 简化静态成员函数调用的方法
- 简化冗余std :: array初始化,当时没有constexpr构造函数
- 正确的方法或设计模式,以简化类中的“operatorX”函数,以按给定顺序比较相同类型的属性
- 指向成员函数的指针与指向数据成员的指针有何不同
- 简化存储在类的 std::vector 成员中的 std::函数的使用
- 双重列表复制构造函数:与单一列表复制构造函数有何不同
- 我如何用功能指针简化C 功能来为类成员函数
- 当我因为模板而无法使用纯虚函数时简化类设计
- C++语言功能可简化命名类型(尤其是在函数声明中)
- 简化函数以检查C 中的`sTD :: set`中是否存在特定值
- C++简化了构造函数重载
- 如何简化模板化回调函数的定义