传递va_list的一部分
Passing part of a va_list
如何传递va_list的一部分或将部分复制到从第n个元素开始的另一个va_list中?
int main (int x, char**argv) {
va_list clientArgs;
va_copy(clientArgs, argv[3]); // get all input parameters after 3rd cmd line arg
foo(clientArgs);
va_end(clientArgs);
....
或者使用va_copy方法…div ?
任何代码都不能移植,甚至不能保证工作(未定义的行为等等)
但是,这是可能的,如下面的代码所示:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>
void VarShowArgs(int n, va_list args)
{
for(int i=0; i<n; ++i)
{
printf("Arg #%d: %dn", i+1, va_arg(args, int));
}
}
void ShowArgs_StartAtFourthParam(int n, ...)
{
va_list args;
int dummy;
va_start(args,n); // n is param #1 (value = 8)
dummy = va_arg(args, int); // Remove Param #2 from args (value = 1)
dummy = va_arg(args, int); // Remove Param #3 from args (value = 2)
// Show arguments starting at Param #4 (which should be value = 3)
VarShowArgs(n - 2, args); // Minus 2 because we removed 2 params from the args.
va_end(args);
}
int main(void)
{
// First param says how many more args there will be.
// This function shows the values starting at the 4th argument (value = 3)
ShowArgs_StartAtFourthParam(8, 1, 2, 3, 4, 5, 6, 7, 8);
getch();
return 0;
}
Arg #1: 3
Arg #2: 4
Arg #3: 5
Arg #4: 6
Arg #5: 7
Arg #6: 8
你不能直接这么做。va_start
的第二个参数应该是函数参数列表中省略号(…)之前的最后一个参数的名称。使用其他任何东西最多只能导致未定义的行为。
为了能够近似你所追求的,你必须知道va_list
前面的值是什么。您可以使用va_arg()
来读取它们,然后将va_list
的剩余部分传递给您的其他函数:
void function(int arg1, char *arg2, ...)
{
va_list args;
va_start(args, arg2);
int i = va_arg(args, int);
double d = va_arg(args, double);
foo(args);
va_end(args);
}
显然,如果变量列表中的参数都是相同类型的,则可以使用循环遍历前N个这样的参数。请注意,没有办法找出提供了多少个参数;你的代码必须"知道"。例如,printf()
使用格式字符串告诉它提供了多少个参数(以及每个参数的类型)。
"va_list的一部分"是什么意思?这个问题不太有意义。
va_list
是一个迭代器对象,允许您一次迭代一个函数的参数——va_start
初始化它以指向当前函数的特定参数之后的参数,而va_arg
获取(复制)当前指向的参数并将其加1以指向下一个参数。
在任何情况下,va_list
都不封装实参列表——它只是一个引用实参列表的抽象指针类对象。
可以将指向va_list
对象的指针传递给其他函数,并让该函数调用va_arg
来处理一些参数。在它返回后,您可以调用va_arg
来处理更多的参数,但这并不是真正意义上的参数列表的副本。
您可以使用va_copy
来复制va_list
,以便有两个迭代器遍历参数列表。然后每个都是独立的,因此每个都将看到va_copy
执行后的所有参数。
没有办法创建一个va_list
对象,它引用的是传递给当前函数的参数...
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- C++:如何使函数只返回作为列表一部分的字符串
- 使用std::list创建循环链表
- 重载Singly Linked List中的赋值运算符
- std::sort()函数无法对向量的一部分进行排序
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 包含 std::list 的结构体的 C++ 初始化
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 如何将文件的一部分读取到std::list缓冲区?