C++模板与泛型 --- typename场合、默认模板参数、趣
2019-05-13 本文已影响33人
307656af5a04
上一节我们学习了类模板的概念,类模板的定义与使用,通过上一节的学习,大家对类模板有一个比较清晰的认识,那么本节,我们继续学习模板与泛型的知识,即typename的使用场合、默认模板参数以及趣味写法分析,希望通过本节的学习,大家能够对模板与泛型的概念有一个更加清晰的认识!
一、typename的使用场合
typename
1、在模板定义里,表明其后的模板参数是类型参数
// 函数模板
// typename后边跟的是一个类型
template<typename T, int a, int b>
int funcaddv2(T c){ ... };
// 类模板
// 名字为T的模板参数
template<typename T>
class myvector { ... };
typename 可以写为class,但是这里的class不是类定义的意思,不能和类定义时的class混淆。
2、使用类的类型成员,用typename标识这是一个类型
::作用域运算符 访问类中的静态成员的时候,类名::静态成员名;
int Time::mystatic = 5;
::还可以用来访问类型成员
template<typename T>
// typename这里的用处就是告诉编译器myiterator是一个类型
typename myvector<T>::myiterator myvector<T>::mybegin()
{
// ............
}
typename 的必须性
::第二个用法,访问类型成员myiterator(typedef);
typename的第二个用法就是告诉编译器myiterator是一个类型;
3、实例
#include <iostream>
using namespace std;
template<typename T>
typename T::size_type getlength(const T&c)
{
if (c.empty())
return 0;
return c.size();
}
int main(int argc, char** argv)
{
string mystr = "I Love China";
// 类似于unsigned int
string::size_type x = getlength(mystr);
printf("%d", x);
system("pause");
return 0;
}
二、函数指针做其他函数的参数
实例
#include <iostream>
using namespace std;
int mf(int tmp1, int tmp2)
{
// .......
return 1;
}
// 我们把函数指针作为某个函数的参数进行传递
// 不加typedef是定义一个函数指针
// 加typedef是定义一个函数指针的类型
typedef int(*FunType)(int, int);
// funcpoint函数指针
void testFunc(int i, int j, FunType funcpoint)
{
// 通过函数指针调用函数
// 相当于调用函数,即调用mf函数
int result = funcpoint(i, j);
cout << result << endl;
}
int main(int argc, char** argv)
{
// 调用函数
testFunc(1, 2, mf);
system("pause");
return 0;
}
三、默认模板趣味用法
实例
#include <iostream>
using namespace std;
int mf(int tmp1, int tmp2)
{
// .......
return 1;
}
// 我们把函数指针作为某个函数的参数进行传递
// 不加typedef是定义一个函数指针
// 加typedef是定义一个函数指针的类型
typedef int(*FunType)(int, int);
// funcpoint函数指针
// void testFunc(int i, int j, FunType funcpoint)
// {
// // 通过函数指针调用函数
// // 相当于调用函数,即调用mf函数
// int result = funcpoint(i, j);
// cout << result << endl;
// }
// 将testFunc改为函数模板
template <typename T,typename F>
void testFunc(const T &i, const T&j, F funcpoint)
{
cout << funcpoint(i, j) << endl;
}
// 可调用对象所代表的类
class tc
{
public:
tc() { cout << "构造函数执行" << endl; }
tc(const tc& t) { cout << "拷贝构造函数执行" << endl; }
// 重载圆括号
int operator()(int v1,int v2)const
{
return v1 + v2;
}
};
int main(int argc, char** argv)
{
// 调用函数
/*tc tpbj;*/
testFunc(3, 4, tc());
system("pause");
return 0;
}
四、默认模板参数
1、类模板,类模板后面必须用<>来提供额外的信息,<>表示信息
// 完全用默认的缺省值
myarray<> abc;
// 提供一个非缺省值,只提供一个,
// 另一个(第二个参数)用的是缺省值
myarray<int> def;
2、函数模板,老模板只能为类模板提供默认模板参数,C++11标准可以为函数模板提供默认参数
#include <iostream>
using namespace std;
// 可调用对象所代表的类
class tc
{
public:
tc() { cout << "构造函数执行" << endl; }
tc(const tc& t) { cout << "拷贝构造函数执行" << endl; }
// 重载圆括号
int operator()(int v1, int v2)const
{
return v1 + v2;
}
};
int mf(int tmp1, int tmp2)
{
// .......
return 1;
}
// 我们把函数指针作为某个函数的参数进行传递
// 不加typedef是定义一个函数指针
// 加typedef是定义一个函数指针的类型
typedef int(*FunType)(int, int);
// 将testFunc改为函数模板
// 定义默认的参数
template <typename T,typename F = tc>
void testFunc(const T &i, const T&j, F funcpoint = F())
{
cout << funcpoint(i, j) << endl;
}
int main(int argc, char** argv)
{
testFunc(3, 4);
system("pause");
return 0;
}
(1)同时给模板参数和函数参数提供缺省值
(2)注意写法 F funcpoint = F()
(3)tc重载()
我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C需要编程,C++需要编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!