C++ 链式可变函数调用
从具有可变参数数的函数中调用类似函数的C++ 链式可变函数调用,c++,c,variadic-functions,C++,C,Variadic Functions,从具有可变参数数的函数中调用类似函数的printf非常容易-只需使用这些函数的v版本(vprintf,vsprintf,CString::FormatV等)。但是如果我把电话挂起来怎么办?下面是简单的代码: #include <stdarg.h> #include <iostream> void direct(const char * _fmt, bool _extra, ...){ va_list args; va_start(args, _extra)
printf
非常容易-只需使用这些函数的v版本(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;
}
我觉得我遗漏了一些明显的东西,但到目前为止还没有弄清楚。请帮助我修复它,以便无论我调用direct
还是chained
代码都能正常工作
将问题标记为C/C++,但我更喜欢C++答案(如果有区别)< /P> 我觉得我遗漏了一些显而易见的东西,但到目前为止还没有弄清楚
是的。实际上,这是从“只需使用这些函数的v版本”开始的。这些函数获得v版本的原因是,正如您所说的,允许链接它们。因此,如果您想为自己的printf-like函数支持它,请确保遵循相同的做法: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);
}
void direct\u v(常量字符*\u fmt、bool\u extra、va\u列表参数){
char-ca[200];
vsprintf(ca,_fmt,args);
标准::cout
我觉得我遗漏了一些显而易见的东西,但到目前为止还没有弄清楚
你做到了。这实际上是从“只使用这些函数的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);
}
void direct\u v(常量字符*\u fmt、bool\u extra、va\u列表参数){
char-ca[200];
vsprintf(ca,_fmt,args);
std::cout不能将调用链接到C风格的变量函数。唯一的方法是将va_list
作为参数传递。这正是需要v*函数族的原因
因此,您可以根据va_list
编写v*-like函数,然后将每个函数包装在基于省略号的可变函数中。您无法链接对C型可变函数的调用。唯一的方法是将va_list
作为参数传递。这正是需要v*函数族的原因
<> p> >按照VAYList编写VC++类函数,然后用省略号函数将每个包封装在一起。 C++中不使用C风格的可变函数。有更好的替代方案。每个代码之前有一个逗号丢失……/>代码> @ ALK -有趣的是,当原型添加到C++时,逗号是Optha。然后C实现了原型,但使逗号成为强制性的,但是在C++中,它仍然是可选的。sigh@alk-是的。我在回答中留下了它,因为它与问题无关,但是如果这是要进入C兼容的标题,逗号必须在那里,你是100%正确的。不要使用C风格的变量函数有趣的是,当原型被添加到C++时,逗号是可选的。然后C++实现原型,但是使逗号成为强制性的。但是C++中仍然是可选的。@ StutyTeLe:难以置信…sigh@alk-是的,我把它留在我的答案里是因为这与问题无关,但如果这是要进入C兼容的标题,逗号必须在那里,你是100%正确的。宾果!(令人尴尬的是,我确实知道va_list
,但完全忘记了这一点)@YePhIcK:怎么可能忘记一些你甚至不知道的东西?;)很简单:输入“did”把它变成了一个“没有”:-PBingo!(令人尴尬的是,我确实知道va_list
,但完全忘记了)@YePhIcK:怎么可能忘记一些你甚至不知道的事情?;)很简单:一个“did”的输入错误把它变成了一个“没有”:-P