我只是想用一个可变数量的参数编写一个非常简单的函数,这样我就可以编写一个类似于printf的函数来进行赋值。查看va_list
的文档后,我不确定为什么此代码会一直给我运行时错误:
这是我的代码:
void print(string sOne , ...);
void main()
{
print("first string", "second string", "third String");
system("pause");
}
void print(string sOne , ...)
{
va_list arguments;
va_start(arguments, sOne);
while ((va_arg(arguments, int)) != 0)
{
string printString = va_arg(arguments, string);
cout << printString;
}
va_end(arguments);
}
答案 0 :(得分:6)
您对可变参数函数的实现非常不正确。
首先,您需要一种方法来告诉函数有多少参数或它们何时结束。标准printf
通过使用格式说明符(它们的数字表示args的数量)来完成此操作,另一个选项是显式提供数字。你似乎期望最后一个参数是整数0(奇怪的选择btw。),但你永远不会将0
作为最后一个参数传递给你的可变函数。
其次,您无法从可变参数函数参数中移植std::string
。完全支持普通类型,对于字符串,您必须使用char*
。 std::string
并不简单,因为它具有非平凡的构造函数和析构函数。有些编译器支持非平凡类型作为此类函数的参数,但其他编译器不支持,因此您不应该尝试这样做。
最后但并非最不重要:变量函数在C ++世界中没有地位,即使是作业也是如此。
答案 1 :(得分:2)
SergeyA解释了为什么你的代码不起作用,这是可能的解决方案之一:
void print(const char *sOne , ...);
int main()
{
print("first string", "second string", "third String", nullptr);
system("pause");
}
void print(const char *sOne , ...)
{
va_list arguments;
va_start(arguments, sOne);
while (sOne)
{
cout << sOne;
sOne = va_arg(arguments, const char *);
}
va_end(arguments);
}
再次举例说明如果你必须使用C风格的可变参数函数,你应该考虑使用C ++ variadic模板。
答案 2 :(得分:0)
因此,您的实施存在一些问题。
va_arg
的来电次数限制,并且:如果
va_arg
中没有更多参数,或者ap
(促销后)中的下一个参数的类型与{{1}不兼容,则调用ap
,行为未定义
T
的一部分传递,您可以使用计数作为第一个参数来清理 1 和 2 :{{1 }} va_list
作为参数传递给void print(int sOne, ...)
,并希望将其推广到const char*
。 va_list
不会为您宣传。它会将您传入的任何内容转换为string
中指定的类型如果您尝试将va_list
视为va_arg
,则最终会出现运行时错误,如您所见。 const char*
作为string
参数进行更正:string
this is only conditionally supported in C++ va_list
以推进"first string"s "second string"s, "third String"s
循环。你需要使用一个计数器。调用va_arg(arguments, const char*)
提取下一个参数,如果参数可用,他们不测试。而是使用您在 2 va_arg
进行这些更改应该让您的代码看起来像这样:
for