c 語言用一些巨集 va_list, va_start, va_arg, va_end 去實現不定數量參數的函式功能, 參數不定量使用省略符號 ... (連續3個句點)來表示, 同時必須明示或暗示後續輸入參數的數量, 像是常用 printf 就可以透過第一個字串參數去得知後續還有多少參數需要擷取利用. 實際上編譯器(compiler)可以得知輸入參數的數量, 只是不易操作, 對程式設計師而言, 不定數量參數有其方便使用的地方, c++ 利用 parameter pack 像是 sizeof...( ) 運算元計算得知輸入有多少數量的參數, 利用 sizeof...( ) 並將函式包裝起來, 可以實現一個不需參數數量的函式, 同時理解樣版函式(template function)的運作方式:
// variadic.c#include <stdio.h>
#include <stdarg.h>
void __expricitFunction(size_t argc, ...) {// 明示後續還有 argc 個數量的參數
va_list args;
va_start(args, argc);
for (int i = 0; i < argc; i++) printf("%d\n", va_arg(args, int) ); // 用整數解釋輸入參數
va_end(args);
}
template
void variadicParameter(List... parameter){// 這是樣版函式, 由 compiler 決定函式型態
__expricitFunction(sizeof...(parameter), parameter...);// 呼叫真正的函式
}
int main( ) {
variadicParameter(1, 2, 3); // 呼叫樣版函式
variadicParameter(4, 5, 6, 7, 8); // 呼叫另一種樣版函式
variadicParameter('a', 'b', 'c', 'd', 'e'); // 呼叫另一種樣版函式
}
上述 typename... List 通常稱為 template parameter pack(一串型態表列, 有些人將通用型態取名為 Args, Rest ...等等都是隨性而取名), 作用是呼叫樣版函式時才指定表列型態(type), 名稱只是一個佔位符號(place holder), 而後續的 List... parameter 則稱為 parameter pack (型態是 List 的表列參數), 用 g++ 編譯並執行:
g++ variadic.c && ./a.out
這是輸出結果:
1
2
3
4
5
6
7
8
97
98
99
100
101
沒有留言:
張貼留言