在看<<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);//也都没有问题