开发者

To invoke a variadic function with unamed arguments of another variadic function

I have two variadic function as foo(format, ...) and bar(format, ...). I want to implement function foo so that it can invoke bar with the same list of arguments it has. That is,

foo(format...)
{
 ...
 bar(format, ...);
}

For instance, invoking foo("(ii)", 1, 2) will invoke bar with same arguments bar("(ii)", 1, 2). How should this foo function be implemented?

PS: function 开发者_运维百科bar is from a legacy library which I cant change its interface.


Can't be done, as long as all you have is a bunch if functions with ... arguments.

You have to plan ahead for things like that and implement each variadic fuinction in two-staged fashion

void vfoo(format, va_list *args) {
  /* Process `*args` */
}

void foo(format, ...) {
  va_list args;
  va_start(args, format);
  vfoo(format, &args);
  va_end(args);
}

Once you have each of your variadic functions implemented through a pair of va_list * function and ... function, you can delegate the calls using the va_list * versions of the functions

void vfoo(format, va_list *args) {
  ...
  vbar(format, args);
  ...
}


GCC can construct function calls at runtime.

foo() {
   void *args = __builtin_apply_args();
   void *ret = __builtin_apply(bar, args, ???);
    __builtin_return(ret);
}

??? is the amount of stack space the arguments take up, which is not necessarily trivial to compute: you will need to understand what the arguments are and architecture-specific details on how they are passed.

Other GCC extensions allow further trickery with macros and inline functions.


Short answer - you cannot. Make bar take a va_list. If you're willing to lock this down to one specific compiler, you could probably do it with inline assembly, but with standard C or C++ it's not possible.

You should, as a general rule, always implement your vararg functions in terms of va_list and then make a wrapper ellipsis function calling the real va_list function.


This works in C++:

#include <iostream>

template<typename Format>
void meheer(const Format& format) {
  std::cout << format << std::endl;;
}

template<typename Format, typename Elt, typename ... Args>
void meheer(const Format& format, const Elt & e, const Args&... args) {
  std::cout << format << e;
  meheer(format, args...);
}

template<typename Format, typename ... Args>
void ohai(const Format& format, const Args&... args) {
  meheer(format, args...);
}

int main(int argc, char ** argv) {
  ohai(1,2,3);

  return EXIT_SUCCESS;
}

Output:

12131

Of course, this is C++0x specific, but it works in my not-super-recent version of gcc. See also: http://en.wikipedia.org/wiki/C%2B%2B0x#Variadic_templates

Update Added full-length example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜