如何利用C++的特性,去實現C中的可變參?

C中的可變參是在cdecl的壓棧順序下,通過va_arg對入參進行指針偏移得到的入參地址。這樣做有明顯的壞處,比如缺少類型檢查。
如果用C++的方式,有沒有更好的辦法實現這個可變參功能呢?

比如找到n個vector數組中最小的那個?

如果不用C++ 11的特性呢?

謝謝大家的回復。我看了一下,sizeof(vector)的大小是固定的,用C的指針偏移的辦法也可以,現在就只差類型檢查了,好像類型檢查沒有辦法。


方法前面的回答講過了。

不準用C加加新標,那還是繼續使用C的方法。

用11新標的話,可變模板參數是正解。實現也並不繁瑣。入參類型安全的printf(...)就可以這麼實現。還支持各個入參類型不同。

如果各入參類型相同,不如用初始化列表模擬下。

原型:

int f(const vector& v) { }

使用:

f({1,2});

f({1,2,3,4});


舉一下可變模板參數的例子吧(C++11及以上):

#include &
#include &

using namespace std;

template &
int func(Arg... x) {

static_assert(sizeof...(x), "Invalid Arg");
int arr[] = {x...};
int res = arr[0];
for(size_t i = 1; i &< sizeof...(x); ++i) if(res &> arr[i]) res = arr[i];
return res;

}

int main() {

cout &<&< func(4, 3, 1, 2) &<&< endl; return 0; }

可以獲得一堆 int 類型的參數中最小的一個(如果傳了奇怪的參數會報錯),其他類型同理。

如果不用C++11的話可能沒有更好的方法。


你可以用variadic template argument,然後假裝他們的類型都一樣。如果調用者傳進去了那些無論如何都兼容不了的類型,就總是會在一個不固定的地方遇到編譯錯誤。


C++不清楚,不過利用C99的新特性,倒是可以實現一種更簡潔的可變參函數。

例如要實現一個求所有參數之和的函數:

double ArrSum( double *arr )
{
double sum = 0.0;
while( *arr == *arr ) sum += *(arr++);
return sum;
}
#define Sum(...) ArrSum( (double[]){__VA_ARGS__,(0.0/0.0)} )


應該多用標準庫的東西。

比如找到n個vector數組中最小的那個?

這個問題有點不好理解啊?n個vector數組,應該說的是這樣的吧

vector arr1[size1];
vector arr2[size2];
...
vector arrn[sizen];

這個要比較大小的話,先得有個less吧。沒有比較規則的話不好做。

暫且把你想做的理解為找到vector中最小的元素,那你可以使用std::min_element。

但是後面你說的,要做類型檢測。這個用C++11的std::is_same就解決了。

如果不用的話,有一個拙計。你可以調用vector特有的一些成員,如果沒有這個成員就會調用出錯。比如說operator[]這個方法,並不是所有的容器都有。但是這不夠,有的也是有的。那就再調用一下resize(vector::size()),因為resize並不是所有的都有。也許這還不夠,那就再找找別的。


你得用宏,然後產生出一堆重載函數


用空指針做參數來實現類型可變?如void smap(void*a,void*b)


推薦閱讀:

一個關於visual studio的問題?
2017年6月,GCC 7.1 對於 C++17 標準的支持情況如何了?
關於VS2015的報錯問題,?
acquire and release semantics in mutex的理解?

TAG:編程 | C編程語言 | C | GCC | 演算法與數據結構 |