在看<<C++ prime>>中遇到了一個問題,看到一半的時候記得書中講數組作爲函數參數時應當提供額外的形參,能夠判定數組的開始和結束。數組
一、數組作爲函數參數的三種方法函數
//額外傳遞一個數組大小的形參spa
int func(int a[],size_t n);
//提供一個數組結束的判定符,例如:C風格的字符串字面值用'\0'判定字符串結束指針
int func(int a[]);//數組a中必需要有判定符
//使用C++標準庫的begin和end函數來獲取一個指向數組首元素和尾元素以後的指針,相似於迭代器code
int func(begin(a),end(a));
二、問題element
咱們仔細觀察最後一種方法,使用begin和end函數的方法,有沒有發現什麼??字符串
既然begin和end是一個函數,並且他們的形參也是一個數組,可是他們爲何沒有提供額外的參數呢?他們是怎麼獲得指向尾元素後面的指針的?想一想咱們本身會怎麼實現:it
咱們本身實現時無非是經過首元素的地址加上數組大小獲得,但是,begin和end並無提供數組大小的形參做爲參數呀。ast
上述問題的答案,其實引出了第四種解決方案,查看C++頭文件,begin和end定義在iterator頭文件中,gcc是定義在bits文件夾下的range_access.h頭文件中,下面是截取該頭文件的部份內容。模板
// <range_access.h> -*- C++ -*- /** * @brief Return an iterator pointing to the first element of the array. * @param __arr Array. */ template<class _Tp, size_t _Nm> inline _Tp* begin(_Tp (&__arr)[_Nm]) { return __arr; } /** * @brief Return an iterator pointing to one past the last element * of the array. * @param __arr Array. */ template<class _Tp, size_t _Nm> inline _Tp* end(_Tp (&__arr)[_Nm]) { return __arr + _Nm; }
看到上面內容,纔想起,書中講到數組引用做爲函數形參時,用函數模板能夠實現給函數傳遞任意大小的數組:
void print (int (&a)[10]);//該函數只能給它傳遞大小爲10的數組做爲實參。 int a[10]={0,1,2,3,4,5,6,7,8,9}; print (a);//正確 int b[3]={1,2,3}; print (b);//錯誤
三、定義函數模板
定義函數模板時不只能夠指定類型參數,還能夠指定非類型參數,例如能夠以下定義print函數
template < typename T, size_t N>//T是類型參數,N是非類型參數 void print (const T (&a)[N] ) { for(const auto &item:a) { cout<<item<<' '; } cout<<endl; } //如今 print(a);//正確 print(b);//也都沒有問題