C++语法学习笔记五十七:typename场合、默认模板参数、趣味写法分析

实例代码:

// 

#include <iostream>
#include <vector>

using namespace std;


//定义类模板
template<typename T> //名字为T的模板参数,用来表示myvector这个容器所保存的元素类型。
class myvector{
public:
	typedef T* myiterator; //迭代器, vector iterator 类型成员。

public:
	myvector(); // 构造函数
	myvector& operator=(const myvector&); //赋值运算符重载。在类模板内部使用模板名并不需要提供模板参数。
	//myvector<T>& operator=(const myvector<T>&);

public:
	myiterator mybegin(); //迭代器的起始位置
	myiterator myend(); //迭代器的最后一个元素的下个位置

public:
	void myfunc();// {}; //把成员函数的函数体(函数具体实现)放在类模板的定义中。

};

//普通函数
template<typename T>
void myvector<T>::myfunc(){
	// ...
	return;
}

//构造函数
template<typename T>
myvector<T>::myvector(){

}

template<typename T>
myvector<T>& myvector<T>::operator=(const myvector&){ //<T>表示返回的是一个实例化了的myvector;
	return *this;
}

template<typename T>
//typename 的必须性
//(a) ::第二个用法,访问类型成员myiterator(typedef)
//typename 这里的目的(用处)就是显式的告诉编译器 myiterator 是一个类型
typename myvector<T>::myiterator myvector<T>::mybegin(){

}


template<typename T>
typename T::size_type getlength(const T&c){
	if (c.empty())
		return 0;
	return c.size();
}

//我们要把函数指针作为某个函数的参数进行传递,怎么做到呢?
//函数指针要想当做 函数的参数就需要:
typedef int(*FunType)(int, int); //定义一个函数指针类型

int mf(int tmp1, int tmp2){
	//...一些代码
	return 1;
}

void testfunc(int i, int j, FunType funcpoint) //funcpoint就是函数指针
{
	//我就可以通过函数指针调用函数:
	int result = funcpoint(i, j); //相当于调用函数, mf
	cout << result << endl;
}

//testfunc(3,4,mf);
//testfunc(3,4,tcobj);
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;
	}
};


//void testfunc(const T &i, const T &j, tc funcpoint = tc())

template<typename T, typename F = tc>
void testfuncv1(const T &i, const T &j, F funcpoint = F()){
	cout << funcpoint(i, j) << endl;
}


template<typename T, typename F = FunType>
void testfuncv2(const T &i, const T &j, F funcpoint = mf){
	cout << funcpoint(i, j) << endl;
}



template<typename T = string, int size = 10>
class myarray{
private:
	T arr[size];
public:
	void myfunc();
};

template<typename T, int size>
void myarray<T, size>::myfunc()
{
	cout << size << endl;
	return;
}


int main()
{
	//一:typename 的使用场合
	//(1) 在模板定义里,表明其后的模板参数是类型参数。
	//typename
	//template<typename T, int a, int b> //typename 后边跟的是一个类型
	//int funcaddv2(T c){ ... };
	//类模板
	//template<class T> //名字为T的模板参数。这里虽然可以用class,但是这里的class不是类定义的意思,不能和类定义时的class混为一谈。
	
	//class myvector {...};
	//typename 可以写为 class

	//(2) 使用类的类型成员,用typename 来标识这是一个类型;
	//::作用域运算符 访问类中的静态成员的时候, 类名::静态成员名,
	//int Time::mystatic = 5;
	//::还可以用来访问类型成员
	//typename 的第二个用法:通知编译器,一个名字代表的是一个类型,这里的typename不能换成class

	string mytest = "I Love China!";
	string::size_type size = getlength(mytest); //类似于unsigned int

	//二:函数指针做其他函数的参数
	//testfunc(3, 4, mf);

	//三:函数模板趣味用法举例
	testfunc(3, 4, mf);

	//这里引入一个概念:可调用对象。 “未归类知识点” 
	tc tcobj;
	testfunc(3, 4, tcobj);
	testfunc(3, 4, tc());  //奇特


	//四:默认模板参数
	//a)类模板,类模板名后边必须用<>来提供额外的信息。 <> 表示这是一个模板;
	myarray<> abc; //完全用模板参数的缺省值
	myarray<int> def; //提供一个非缺省值,只提供一个,另外一个(第二个参数) 用的是缺省值。

	//b) 函数模板:老标准只能为类模板提供默认模板参数,C++新标准可以为函数模板提供默认参数;
	testfuncv1(3, 4);
	//(1) 同时给模板参数和函数参数提供缺省值
	//(2) 注意写法 F funcpoint = F()
	//(3) tc重载()




	system("pause");
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值