泛型编程
1.指针的算术运算
为了操作容器中的数据而不用管它的数据类型是什么,使用泛型(generic)算法,不直接在容器身上进行操作,而是借用一对iterator,标识我们要进行迭代的范围。
1.对于array来说,传入array而不管array里面是什么
//写出template泛型 find()函数
template <typename T>
T* find( T *first, T *last, const T &value) {
if (!first || !last)
return 0;
for (; first != last; ++first) {
if (*first == value)
return first;//输出所查找元素的地址
}
return 0;
}
int main(){
int ia[8] = { 1,2,3,4,5,6,7,8 };
int *pi = find(ia,ia+8,ia[3]); //find()返回所查找元素的地址
}
2.传入vector而不管vector里面是什么
#include <vector>
#include <iostream>
//编写泛型find函数
template <typename T>
T* find( T *first, T *last, const T &value) {
if (!first || !last)
return 0;
for (; first != last; ++first) {
if (*first == value)
return first;
}
return 0;
}
template <typename T>
inline T * begin(const std::vector<T> &vec) {
return vec.std::empty() ? 0 : &vec[0];
}
template <typename T>
inline T * end(const std::vector<T>&vec) {
return vec.std::empty() ? 0 : &vec[vec.std::size()];
}
int main() {
int ia[8] = { 1,2,3,4,5,6,7,8 };
std::vector<int> ib;
ib.insert(ib.begin(), ia, ia + 9);
std::cout << "ib is " << &ib << "\nib[7]is" << &ib[7]
<<"\nia is "<<ia<<"\nia[7] is "<<&ia[7];//验证了vector和array确实都是连续内存
int *pi = find(begin(ib),end(ib),ib[3]);//why:find报错
//std::cout << find(begin(ib), end(ib), ib[3]) << " ";
getchar();
}
但是对于list等非连续空间内的指针,指针的算术运算就不适用了,因此需要在底层指针的行为之上提供一层抽象,取代程序原本的“指针直接操作”方式,我们把底层指针的处理放在这个抽象层当中,让用户无须直接面对指针操作。这样就可以只提供一个find()函数就可以操作std所提供的所有的容器类。
#include <vector>
#include <iostream>
#include <string>
#include <list>
std::vector<std::string> svec;
std::vector<std::string>::iterator iter = svec.begin();
namespace mine {
template <typename T, typename IT>
IT find(IT first, IT last, const T &value)
{
for (; first != last; ++first) {
if (value == *first)//值运算,故first解包
return first;
}
return last;
}
}
/*发现如果用find(),会和标准库的find()重名,导致报错“有多个重载函数find实例与
参数列表匹配,函数调用不明确”
问题原因:自定义的find定义位置是全局变量,因此污染了namespace
解决方法:1.函数改名 ,并以后不要定义与标准库重名的函数
2.给自定义变量加命名空间 如 namespace main{}*/
int main() {
const int asize = 8;
int ia[asize] = { 1,1,2,3,5,8,13,21 };//ia is an array
std::vector<int> ivec(ia,ia+asize);//将ia[]赋值给vector
std::list<int> ilist(ia, ia + asize);
//find() return一个地址,故应该和pia存放的地址对比计算
int*pia = mine::find(ia, ia + asize, 1024);
if (pia != ia + asize)//pia is an int*
std::cout << pia << std::endl;
else
std::cout << "none"<<std::endl;
std::vector<int>::iterator it; //声明泛型迭代器it
it = mine::find(ivec.begin(), ivec.end(), 21);
if(it!=ivec.end())
std::cout << *it << std::endl;
else
std::cout << "none";
getchar();
}
因此,定义函数时最好不要定义和标准库同名的函数名。
来源:CSDN
作者:abyss_miracle
链接:https://blog.csdn.net/abyss_miracle/article/details/103692526