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

Not*_*ble 101 c++ variadic-functions

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

void example(int a, int b, ...);
void exampleB(int b, ...);
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*ler 115

你不能直接做到; 你必须创建一个带有va_list:

#include <stdarg.h>

static void exampleV(int b, va_list args);

void exampleA(int a, int b, ...)    // Renamed for consistency
{
    va_list args;
    do_something(a);                // Use argument a somehow
    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...
}
Run Code Online (Sandbox Code Playgroud)

  • 怀疑我不得不做这样的事情,问题是示例函数基本上是vsprintf的包装器而不是其他:/ (2认同)

Vin*_*ond 27

也许在这里扔一个池塘里的岩石,但它似乎与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);
}
Run Code Online (Sandbox Code Playgroud)

至少,它适用于g++.

  • 我简直不敢相信要找到一个如何使用这个已有 10 年历史的便利功能的示例是多么困难 (4认同)

ten*_*our 15

你应该创建这些函数的版本,这些函数采用va_list,并传递它们.再看vprintf一个例子:

int vprintf ( const char * format, va_list arg );
Run Code Online (Sandbox Code Playgroud)


小智 8

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

如何将可变数量的参数传递给 printf/sprintf

我对性能完全不感兴趣(我确信这段代码可以通过多种方式改进,随意这样做:)),这仅用于一般调试打印,所以我这样做了:

//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;
}
Run Code Online (Sandbox Code Playgroud)

然后我可以像这样使用

Point2d p;

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

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


小智 7

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

#define exampleB(int b, ...)  example(0, b, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)