Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VAYLIST C++的故障_C++_Arguments_Variable Assignment_Variadic Functions - Fatal编程技术网

VAYLIST C++的故障

VAYLIST C++的故障,c++,arguments,variable-assignment,variadic-functions,C++,Arguments,Variable Assignment,Variadic Functions,我只是想写一个非常简单的函数,它的参数个数可变,所以我可以为赋值写一个类似printf的函数。在查看了文档之后,我不确定为什么这段代码总是给我运行时错误: 这是我的密码: void print(string sOne , ...); void main() { print("first string", "second string", "third String"); system("pause"); } void print(string sOne , ...) {

我只是想写一个非常简单的函数,它的参数个数可变,所以我可以为赋值写一个类似printf的函数。在查看了文档之后,我不确定为什么这段代码总是给我运行时错误:

这是我的密码:

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);
}

你对可变函数的实现是非常不正确的

首先,您需要一种方法来告诉函数有多少个参数或它们何时结束。标准printf通过使用格式说明符来实现这一点。它们的编号表示参数的编号,另一个选项是显式提供编号。您似乎期望最后一个参数是整数0,顺便说一句,但您从未将0作为最后一个参数传递给变量函数

其次,您不能从可变函数参数中以可移植的方式提取std::string。只完全支持普通类型,对于字符串,必须使用char*。字符串不是平凡的,因为它有非平凡的构造函数和析构函数。某些编译器确实支持非平凡类型作为此类函数的参数,但其他编译器不支持,因此您不应该尝试这种方法


最后一点,但并非最不重要:变量函数在C++世界中没有位置,甚至对于赋值也没有。

所以,你的实现有几个问题。 您没有通过对和的呼叫数量的限制: 如果在ap中没有更多参数时调用va_arg,或者如果升级后ap中下一个参数的类型与T不兼容,则行为未定义

您似乎想要打印第一个字符串,因此需要将其作为va_列表的一部分传递,您可以使用计数作为第一个参数来清除1和2:void printint sOne。。。 您正在将const char*s作为参数传递给va_列表,并希望它将这些参数提升为字符串。va_列表不会为您升级。它将您传入的任何内容强制转换为在va_arg中指定的类型,如果您尝试将const char*视为字符串,则会出现运行时错误,如您所见。这可以通过使用字符串作为va_列表参数来纠正:第一个字符串第二个字符串第三个字符串需要使用va_argarguments、const char* 您正在调用va_arg以推进for循环。你需要用一个柜台。调用va_arg提取下一个参数,它们不会测试参数是否可用。相反,使用作为2的一部分传入的计数,自动i=0;我知道++我 进行这些更改会使您的代码看起来像这样:

void print(int sOne, ...) {
    va_list arguments;
    va_start(arguments, sOne);

    for (auto i = 0; i < sOne; ++i) {
        cout << va_arg(arguments, const char*) << endl;
    }
    va_end(arguments);
}

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++的可变模板。Valad函数是元编程的基本要求。@ Jonathan Mee C++有可变模板和初始化列表,你还需要什么?“瓦乌名单只是一份遗产,”杰斯佩朱尔说,他们是。在表达式SFINAE出现之前。你经常需要va_list来利用Varadic模板,尽管我同意在很多情况下,这种模板的封装已经成熟了。@JesperJuhl,我想,他提到了几十年来检查成员是否存在的老把戏。请将您的运行时错误作为问题的一部分发布。@RickSmith我在我的系统上得到的错误中添加了一个,它是由impropper使用调用堆栈中的何处发生错误引起的?@ivan_pozdeev在线:string printString=va_arguments,string;谢谢你发布你的错误。请编辑您的问题,不要使用错误的图像。这将使以后更容易搜索您的问题。未定义的行为。如果在以下情况下调用va_arg。。。升级后ap中下一个参数的类型与T不兼容,行为未定义…@SergeyA我同意。。。但我想你是因为我的答案不正确才发的吧?你能解释一下你的陈述和我说的有什么冲突吗?在这个例子中,实际的论点类型是const char*。std::string不是const char*的兼容类型,并且const char*无法升级为std::string。因此,va_argarguments,string运动未定义的行为。@SergeyA投票前你读过我的答案吗?请密切注意3:以下是详细信息