2011-03-21 86 views
8

我有兩個可變參數函數foo(format, ...)bar(format, ...)。我想實現功能foo,以便它可以調用bar具有相同的參數列表。也就是說,使用另一個可變參數函數的未命名參數調用可變參數

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

例如,調用foo("(ii)", 1, 2)將調用bar與相同參數bar("(ii)", 1, 2)foo函數應該如何實現?

PS:功能bar來自遺留庫,我不能改變它的接口。

+0

重複http://stackoverflow.com/questions/150543/forward-an-invocation-of-a-variadic-function-in-c – 2011-03-21 21:32:41

+1

我不知道你想完成什麼,但我幾乎願意打賭你會發現下面的標準庫函數很方便:'vprintf()','vfprintf()'和'vsprintf()'。 – 2011-03-21 21:34:50

回答

11

無法完成,只要你擁有的是一堆如果功能與...論點。

你必須提前計劃之類的東西,並實現每可變參數fuinction在兩階段的方式

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

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

一旦你有每通過一對va_list *功能和...功能的實現你的可變參數的功能,你可以使用va_list *版本的功能

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

簡答 - 你不能。使酒吧採取va_list。如果你願意把它鎖定到一個特定的編譯器上,你可以用內聯彙編來完成,但使用標準的C或C++是不可能的。

作爲一般規則,您應該始終按照va_list來實現您的可變參數函數,然後使用包裝函數省略號函數調用實際的va_list函數。

+0

我有點不同意'簡答題'。它可以通過可變參數模板在C++ 0x中完成(見其他地方的答案)。我只是去了問題標籤 - 特別是C++ :) – phooji 2011-03-21 21:08:26

+0

...內聯程序集或特定於編譯器的擴展... – 2011-03-21 21:09:16

+0

@Max Lybbert:這些中的哪一個會是C++ 0x? – phooji 2011-03-21 21:19:25

1

這個工作在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; 
} 

輸出:

12131 

當然,這是C++ 0x中特有的,但它在我沒有超最近版本的GCC的工作。另請參閱:http://en.wikipedia.org/wiki/C%2B%2B0x#Variadic_templates

更新添加了完整長度示例。

6

GCC can construct function calls at runtime

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

???是堆棧空間的參數佔用,這不一定是微不足道的計算量:您需要了解的參數是和它們是如何通過特定架構的詳細信息。

其他GCC擴展允許進一步欺騙宏和內聯函數。

+0

+1用於解答我的問題。先生,先生/女士。 – phooji 2011-03-21 21:26:20

+0

現在*這*確實非常酷! – alecov 2016-01-30 12:21:51

相關問題