YeP*_*IcK 1 c c++ variadic-functions
一printf
类函数从不同的参数个数函数调用很容易足以让-只使用一个v的那些功能(-version vprintf
,vsprintf
,CString::FormatV
,等)。但是,如果我将呼叫链接起来怎么办?这是简单的代码:
#include <stdarg.h>
#include <iostream>
void direct(const char * _fmt, bool _extra, ...){
va_list args;
va_start(args, _extra);
char ca[200];
vsprintf(ca, _fmt, args);
std::cout << ca << std::endl;
va_end(args);
}
void chained(const char * _fmt, ...){
va_list args;
va_start(args, _fmt);
direct(_fmt, false, args);
va_end(args);
}
int main(){
direct("direct works just fine: %d", false, 1);
chained("indirect produces garbage: %d", 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例输出如下:
direct works just fine: 1
indirect produces garbage: 1951661256
Run Code Online (Sandbox Code Playgroud)
我觉得我缺少明显的东西,但到目前为止还不能弄清楚。请帮助我修复它,以便无论我调用direct
还是chained
代码都能正常工作。
将问题标记为C / C ++,但我更喜欢C ++答案(如果有所不同)
我觉得我遗漏了一些明显的东西,但到目前为止还无法弄清楚
你做到了 这实际上是您开始的:“仅使用这些函数的v版本”。这些函数获得v版本的原因是允许将它们链接起来,就像您所说的那样。因此,如果要为自己的类似于printf的功能支持它,请确保遵循相同的做法:
void direct_v(const char * _fmt, bool _extra, va_list args){
char ca[200];
vsprintf(ca, _fmt, args);
std::cout << ca << std::endl;
}
void direct(const char * _fmt, bool _extra...){
va_list args;
va_start(args, _extra);
direct_v(_fmt, _extra, args);
va_end(args);
}
void chained(const char * _fmt...){
va_list args;
va_start(args, _fmt);
direct_v(_fmt, false, args);
va_end(args);
}
Run Code Online (Sandbox Code Playgroud)
这样拆分的一个很好的新兴特性direct
是,您可以更好地分离关注点。包装器会处理va_list
相关的位,而v函数仅关心列表需要完成的工作,因此可以在此处重用。
编辑前注意:顺便说一句,如果确实需要C兼容性,则函数原型需要使用逗号将最后一个参数与省略号分开。您使用的语法仅是C ++。