将变量参数传递给另一个接受变量参数列表的函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将变量参数传递给另一个接受变量参数列表的函数相关的知识,希望对你有一定的参考价值。

所以我有2个函数都有相似的参数

void example(int a, int b, ...);
void exampleB(int b, ...);

现在example调用exampleB,但是如何在不修改exampleB的情况下传递变量参数列表中的变量(因为这已经在别处使用过了)。

答案

你不能直接做;你必须创建一个需要va_list的函数:

#include <stdarg.h>

static void exampleV(int b, va_list args);

void example(int a, int b, ...)
{
    va_list args;
    va_start(args, b);
    exampleV(b, args);
    va_end(args);
}

void exampleB(int b, ...)
{
    va_list args;
    va_start(args, b);
    exampleV(b, args);
    va_end(args);
}

static void exampleV(int b, va_list args)
{
    ...whatever you planned to have exampleB do...
    ...except it calls neither va_start nor va_end...
}
另一答案

也许在这里扔一个岩石池,但它似乎与C ++ 11可变参数模板工作得很好:

#include <stdio.h>

template<typename... Args> void test(const char * f, Args... args) {
  printf(f, args...);
}

int main()
{
  int a = 2;
  test("%s\n", "test");
  test("%s %d %d %p\n", "second test", 2, a, &a);
}

至少,它适用于g++

另一答案

你应该创建这些函数的版本,这些函数采用va_list,并传递它们。以vprintf为例:

int vprintf ( const char * format, va_list arg );
另一答案

我还想包装printf并在这里找到一个有用的答案:

How to pass variable number of arguments to printf/sprintf

我对性能一点也不感兴趣(我确信这段代码可以通过多种方式进行改进,随意这样做:)),这只适用于一般的debugprinting,所以我这样做了:

//Helper function
std::string osprintf(const char *fmt, ...)
{
    va_list args;
    char buf[1000];
    va_start(args, fmt);
    vsnprintf(buf, sizeof(buf), fmt, args );
    va_end(args);
    return buf;
}

然后我就可以这样使用了

Point2d p;

cout << osprintf("Point2d: (%3i, %3i)", p.x, p.y);
instead of for example:
cout << "Point2d: ( " << setw(3) << p.x << ", " << p.y << " )";

c ++ ostreams在某些方面很漂亮,但实际上如果你想打印这样的东西,并在数字之间插入一些小字符串,如括号,冒号和逗号,就会变得可怕。

另一答案

顺便提一下,许多C实现都有内部v?printf变体,恕我直言应该是C标准的一部分。具体细节各不相同,但典型的实现将接受包含字符输出函数指针的结构和说明应该发生什么的信息。这允许printf,sprintf和fprintf都使用相同的“核心”机制。例如,vsprintf可能是这样的:

void s_out(PRINTF_INFO *p_inf, char ch)
{
  (*(p_inf->destptr)++) = ch;
  p_inf->result++;
}

int vsprintf(char *dest, const char *fmt, va_list args)
{
  PRINTF_INFO p_inf;
  p_inf.destptr = dest;
  p_inf.result = 0;
  p_inf.func = s_out;
  core_printf(&p_inf,fmt,args);
}

然后core_printf函数为每个要输出的字符调用p_inf-> func;然后输出函数可以将字符发送到控制台,文件,字符串或其他内容。如果一个人的实现暴露了core_printf函数(以及它使用的任何设置机制),那么可以使用各种变体扩展它。

另一答案

基于你正在包装vsprintf的评论,并且这被标记为C ++我建议不要尝试这样做,但是改变你的界面来改为使用C ++ iostreams。它们比print功能系列具有优势,例如类型安全性和能够打印printf无法处理的物品。现在进行一些返工可以在将来节省大量的痛苦。

另一答案

一种可能的方法是使用#define:

#define exampleB(int b, ...)  example(0, b, __VA_ARGS__)
另一答案

使用新的C ++ 0x标准,您可以使用可变参数模板完成此操作,甚至可以将旧代码转换为新模板语法而不会破坏任何内容。

以上是关于将变量参数传递给另一个接受变量参数列表的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何将引用函数传递给另一个函数

C++:如何将变量作为参数传递给类构造函数

理解JavaScript中的回调函数

将表变量作为参数传递给表值函数

将一个值列表而不是多个参数传递给函数?

将多个参数传递给Powershell中的函数变量[重复]