2015-11-02 112 views
2

「連續撥打」是指一個函數調用這樣的(我有沒有更好的詞):如何在C語言中實現「連續調用」語法糖?

foo(arg1,...)(arg2_1,...); 

它等同於:

foo(arg1,...); 
foo(arg2_1,...); 

我認爲我們可以返回一個指針誰是自己實施it.So這段代碼運行良好:

typedef int (*f_p)(); //*note* here I always must indicate a 'int' or any other type 
f_p print_two_num (int a , int b) 
{ 
printf ("%d,%d\n", a, b); 
return print_two_num; 
} 
//omit main() 
print_two_num(1,2)(3,4); 

但我不能這樣調用函數:

print_two_num(1,2)(3,4)(5,6); 

因爲print_two_num(1,2)(3,4)會返回一個「廉政」類型(儘管我們可以通過((f_p)(print_two_num(4,5)(2,3)))(6,7)),但醜叫) 所以我們可以改變這樣的代碼:

typedef int (*f_p1)(); 
typedef f_p1 (*f_p2)(); 
f_p2 print_two_num (int a , int b) 
{ 
//... 
return print_two_num; 
} 

但它不能像print_two_num(1,2)(3,4)(5,6)(7,8)這樣的電話,因爲它在上次通話中仍然會出錯。

現在,如何實現無限制的「連續通話」,我可以調用如下函數:foo()()()()()... ...

我找不到解決'遞歸定義'問題的好方法。

我知道這句法糖沒有實際的幫助,我只是好奇:P

+2

對於這個工作,你必須做一個遞歸類型的別名(在'f_p '類別別名需要引用它自己),這是不可能的。所以總之不能用標準C來完成。 –

+0

你爲什麼要問?詳細瞭解[關閉](http://en.wikipedia.org/wiki/Closure_%28computer_programming%29)。使用[GCC](http://gcc.gnu.org/),你可能會有一個宏'DO',它擴展到一些聰明的[語句表達式](https://gcc.gnu.org/onlinedocs/gcc/Statement -Exprs.html) –

回答

3

你的部分解決方案是不是標準的conpliant,就證明了編譯器警告。您需要顯式強制轉換以在指針類型之間進行轉換。如果使用了強制轉換,則會調用未定義的行爲,因爲在調用指針之前必須將指針轉回原始類型。

不能在C.

如果你真的想使用這個確切的語法,你可以這樣做:

#include <stdio.h> 

typedef struct chain (*f_p)(int, int); 

struct chain 
{ 
    f_p also; 
}; 

struct chain print_two_num (int a , int b) 
{ 
    printf ("%d,%d\n", a, b); 
    struct chain ret; 
    ret.also = print_two_num; 
    return ret; 
} 

int main() 
{ 
    print_two_num(1,2).also(3,4).also(5,6); 
}