2012-07-21 13 views
0

我想爲一堆函數編寫一個C++包裝器,這些函數在它們的功能上都很相似。但他們都有不同的論點。例如(假定的typeA,TYPEB等不同類型的typedef定義):使用可變數量的參數爲不同函數寫一個通用包裝器

typeA func1 (typeB b, typeC c); 

typeA func2 (typeB b, typeD d, typeE e); 

這些是我想寫(注意兩個有返回類型的typeA和類型的TypeB的第一個參數的包裝功能)。所以我打算創建一個通用包裝類,並在構造函數中存儲參數列表。我希望能夠調用一個函數,它看起來像下面的「功能」:

class wrapper { 
    public: 
    wrapper (/*args - a list of arguments, including 
       a pointer to the actual function, and 
       the remaining arguments depending 
       on the function. */); 
    void func (typeB b, typeA &a); 
} 

所以,我想在這樣一種方式,它調用任何函數(或者FUNC1或FUNC2)寫FUNC用參數傳遞給構造函數。

我想知道是否有方法可以將func1或func2視爲具有可變數量的參數。或者至少,如果在C++中有一種方法可以提供函數和參數列表並獲取eval(function,argument_list)。

另一種方法是爲每一個函數編寫一個包裝,我想避免但不反對。 (另外,我不介意如果一個解決方案涉及我不使用包裝類,但包裝功能)

+1

你熟悉的std ::功能,什麼編譯和版本?增強可用嗎? – Zac 2012-07-21 06:55:17

+0

你想用你的包裝完成什麼?我不明白爲什麼要包裝任何東西。 – Adam 2012-07-21 07:43:23

+0

@Zac,我看着std :: function。看起來好像我仍然需要指定一個確切數量的輸入參數才能與另一個函數一起使用。我在Ubuntu上工作。我在終端上運行了g ++ --version,它告訴我4.6.1。是的。 Boost可用。我聽說它可能對我想要做的事有用。 – 2012-07-21 23:12:55

回答

0

這是我在C做的事情,以環繞任何功能。我希望它能幫助/激勵你。 主要的限制是你只能圍繞用戶定義的函數進行換行,因爲你將不得不修改函數的簽名。

我的解決方案使用va_arg結構。

#include <stdarg.h> 
void * super_wrapper(void * (*fn)(), void * ret, int n, ...) 
{ 
    va_list = my_list; 
    va_start(my_list, n); 
    ret = (*fn)(ret, n, my_list); 
    va_end(my_list); 
    return ret 
} 

包裝的簽名採用指針要執行的功能,指針給函數來獲取你的回報價值,悠逸的參數個數調用函數,然後你想要調用的函數的參數。

va_list是參數列表。 你用va_start初始化它。 va_start的第一個參數是你想要初始化的va_list。第二個參數是當前函數的最後一個已知參數(在本例中爲'n')。

現在,您將使用自定義函數中的省略號而不是va_list。我

兩個例子有:

double sum (int n, ...) 
{ 
    int i; 
    double res = 0; 
    double tmp; 
    va_list = my_list; 
    va_start(my_list, n); 
    for(i=0; i<n; i++) 
    { 
    tmp = va_arg(my_list, double); 
    res += tmp; 
    } 
    va_end(my_list); 
    return res; 
} 

void my_print(int n, ...) 
{ 
    int i; 
    va_list my_list; 
    va_start(my_list, n); 
    char * tmp; 
    for(i=0; i<n; i++) 
    { 
    tmp = va_arg(my_list, char *); 
    printf("%s ", tmp); 
    } 
    printf("\n"); 
    va_end(my_list); 
} 

我設法使用相同的包裝來調用這個兩個不同的功能與簽名,並在函數體一些修改。 問題是,在參數和回報中,我只給出指針。所以我必須解除指針的引用。

void * sum (void * ret, int n, va_list my_list) 
{ 
    int i; 
    double res = 0; 
    double *tmp; 
    for(i=0; i<n; i++) 
    { 
    tmp = va_arg(my_list, double); 
    res += *tmp; 
    } 
    ret = &res; 
    return ret; 
} 

void* my_print(int n, ...) 
{ 
    int i; 
    char ** tmp; 
    for(i=0; i<n; i++) 
    { 
    tmp = va_arg(my_list, char **); 
    printf("%s ", *tmp); 
    } 
    printf("\n"); 
    return ret; 
} 

現在我可以使用相同的包裝函數在我的主要調用這兩個函數:

void main() 
{ 
    double two = 2.0; 
    double three = 3.0; 
    double fifteen = 15.0; 

    char *I, *am, *a, *great, *wrapper; 
    I = malloc(sizeof(char) * 2); 
    am = malloc(sizeof(char) * 3); 
    a = malloc(sizeof(char)*2); 
    great = malloc(sizeof(char) * 6; 
    wrapper = malloc(sizeof(char) * 8); 

    I = strcpy(I, "I\0"); 
    am = strcpy(am, "am\0"); 
    a = strcpy(a,"a\0"); 
    great = strcpy(great, "great\0"); 
    wrapper = strcpy(wrapper, "wrapper\0"); 

    void * ret; 

    printf("Sum = %f\n", *((double*)super_wrapper(sum, ret, 3, &two, &three, &fifteen))); 
    super_wrapper(my_print, ret, 5, &I, &am, &a, &great, &wrapper); 
} 
相關問題